Flappy Bird PDS II
json.hpp
Go to the documentation of this file.
1 // __ _____ _____ _____
2 // __| | __| | | | JSON for Modern C++
3 // | | |__ | | | | | | version 3.12.0
4 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5 //
6 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
7 // SPDX-License-Identifier: MIT
8 
9 /****************************************************************************\
10  * Note on documentation: The source files contain links to the online *
11  * documentation of the public API at https://json.nlohmann.me. This URL *
12  * contains the most recent documentation and should also be applicable to *
13  * previous versions; documentation for deprecated functions is not *
14  * removed, but marked deprecated. See "Generate documentation" section in *
15  * file docs/README.md. *
16 \****************************************************************************/
17 
18 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
19 #define INCLUDE_NLOHMANN_JSON_HPP_
20 
21 #include <algorithm> // all_of, find, for_each
22 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
23 #include <functional> // hash, less
24 #include <initializer_list> // initializer_list
25 #ifndef JSON_NO_IO
26  #include <iosfwd> // istream, ostream
27 #endif // JSON_NO_IO
28 #include <iterator> // random_access_iterator_tag
29 #include <memory> // unique_ptr
30 #include <string> // string, stoi, to_string
31 #include <utility> // declval, forward, move, pair, swap
32 #include <vector> // vector
33 
34 // #include <nlohmann/adl_serializer.hpp>
35 // __ _____ _____ _____
36 // __| | __| | | | JSON for Modern C++
37 // | | |__ | | | | | | version 3.12.0
38 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
39 //
40 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
41 // SPDX-License-Identifier: MIT
42 
43 
44 
45 #include <utility>
46 
47 // #include <nlohmann/detail/abi_macros.hpp>
48 // __ _____ _____ _____
49 // __| | __| | | | JSON for Modern C++
50 // | | |__ | | | | | | version 3.12.0
51 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
52 //
53 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
54 // SPDX-License-Identifier: MIT
55 
56 
57 
58 // This file contains all macro definitions affecting or depending on the ABI
59 
60 #ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
61  #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
62  #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0
63  #warning "Already included a different version of the library!"
64  #endif
65  #endif
66 #endif
67 
68 #define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
69 #define NLOHMANN_JSON_VERSION_MINOR 12 // NOLINT(modernize-macro-to-enum)
70 #define NLOHMANN_JSON_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum)
71 
72 #ifndef JSON_DIAGNOSTICS
73  #define JSON_DIAGNOSTICS 0
74 #endif
75 
76 #ifndef JSON_DIAGNOSTIC_POSITIONS
77  #define JSON_DIAGNOSTIC_POSITIONS 0
78 #endif
79 
80 #ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
81  #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
82 #endif
83 
84 #if JSON_DIAGNOSTICS
85  #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
86 #else
87  #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
88 #endif
89 
90 #if JSON_DIAGNOSTIC_POSITIONS
91  #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS _dp
92 #else
93  #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS
94 #endif
95 
96 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
97  #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
98 #else
99  #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
100 #endif
101 
102 #ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
103  #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
104 #endif
105 
106 // Construct the namespace ABI tags component
107 #define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) json_abi ## a ## b ## c
108 #define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c) \
109  NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c)
110 
111 #define NLOHMANN_JSON_ABI_TAGS \
112  NLOHMANN_JSON_ABI_TAGS_CONCAT( \
113  NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
114  NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON, \
115  NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS)
116 
117 // Construct the namespace version component
118 #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
119  _v ## major ## _ ## minor ## _ ## patch
120 #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
121  NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
122 
123 #if NLOHMANN_JSON_NAMESPACE_NO_VERSION
124 #define NLOHMANN_JSON_NAMESPACE_VERSION
125 #else
126 #define NLOHMANN_JSON_NAMESPACE_VERSION \
127  NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
128  NLOHMANN_JSON_VERSION_MINOR, \
129  NLOHMANN_JSON_VERSION_PATCH)
130 #endif
131 
132 // Combine namespace components
133 #define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
134 #define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
135  NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
136 
137 #ifndef NLOHMANN_JSON_NAMESPACE
138 #define NLOHMANN_JSON_NAMESPACE \
139  nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
140  NLOHMANN_JSON_ABI_TAGS, \
141  NLOHMANN_JSON_NAMESPACE_VERSION)
142 #endif
143 
144 #ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
145 #define NLOHMANN_JSON_NAMESPACE_BEGIN \
146  namespace nlohmann \
147  { \
148  inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
149  NLOHMANN_JSON_ABI_TAGS, \
150  NLOHMANN_JSON_NAMESPACE_VERSION) \
151  {
152 #endif
153 
154 #ifndef NLOHMANN_JSON_NAMESPACE_END
155 #define NLOHMANN_JSON_NAMESPACE_END \
156  } /* namespace (inline namespace) NOLINT(readability/namespace) */ \
157  } // namespace nlohmann
158 #endif
159 
160 // #include <nlohmann/detail/conversions/from_json.hpp>
161 // __ _____ _____ _____
162 // __| | __| | | | JSON for Modern C++
163 // | | |__ | | | | | | version 3.12.0
164 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
165 //
166 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
167 // SPDX-License-Identifier: MIT
168 
169 
170 
171 #include <algorithm> // transform
172 #include <array> // array
173 #include <forward_list> // forward_list
174 #include <iterator> // inserter, front_inserter, end
175 #include <map> // map
176 #ifdef JSON_HAS_CPP_17
177  #include <optional> // optional
178 #endif
179 #include <string> // string
180 #include <tuple> // tuple, make_tuple
181 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
182 #include <unordered_map> // unordered_map
183 #include <utility> // pair, declval
184 #include <valarray> // valarray
185 
186 // #include <nlohmann/detail/exceptions.hpp>
187 // __ _____ _____ _____
188 // __| | __| | | | JSON for Modern C++
189 // | | |__ | | | | | | version 3.12.0
190 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
191 //
192 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
193 // SPDX-License-Identifier: MIT
194 
195 
196 
197 #include <cstddef> // nullptr_t
198 #include <exception> // exception
199 #if JSON_DIAGNOSTICS
200  #include <numeric> // accumulate
201 #endif
202 #include <stdexcept> // runtime_error
203 #include <string> // to_string
204 #include <vector> // vector
205 
206 // #include <nlohmann/detail/value_t.hpp>
207 // __ _____ _____ _____
208 // __| | __| | | | JSON for Modern C++
209 // | | |__ | | | | | | version 3.12.0
210 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
211 //
212 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
213 // SPDX-License-Identifier: MIT
214 
215 
216 
217 #include <array> // array
218 #include <cstddef> // size_t
219 #include <cstdint> // uint8_t
220 #include <string> // string
221 
222 // #include <nlohmann/detail/macro_scope.hpp>
223 // __ _____ _____ _____
224 // __| | __| | | | JSON for Modern C++
225 // | | |__ | | | | | | version 3.12.0
226 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
227 //
228 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
229 // SPDX-License-Identifier: MIT
230 
231 
232 
233 #include <utility> // declval, pair
234 // #include <nlohmann/detail/meta/detected.hpp>
235 // __ _____ _____ _____
236 // __| | __| | | | JSON for Modern C++
237 // | | |__ | | | | | | version 3.12.0
238 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
239 //
240 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
241 // SPDX-License-Identifier: MIT
242 
243 
244 
245 #include <type_traits>
246 
247 // #include <nlohmann/detail/meta/void_t.hpp>
248 // __ _____ _____ _____
249 // __| | __| | | | JSON for Modern C++
250 // | | |__ | | | | | | version 3.12.0
251 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
252 //
253 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
254 // SPDX-License-Identifier: MIT
255 
256 
257 
258 // #include <nlohmann/detail/abi_macros.hpp>
259 
260 
262 namespace detail
263 {
264 
265 template<typename ...Ts> struct make_void
266 {
267  using type = void;
268 };
269 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
270 
271 } // namespace detail
273 
274 
276 namespace detail
277 {
278 
279 // https://en.cppreference.com/w/cpp/experimental/is_detected
280 struct nonesuch
281 {
282  nonesuch() = delete;
283  ~nonesuch() = delete;
284  nonesuch(nonesuch const&) = delete;
285  nonesuch(nonesuch const&&) = delete;
286  void operator=(nonesuch const&) = delete;
287  void operator=(nonesuch&&) = delete;
288 };
289 
290 template<class Default,
291  class AlwaysVoid,
292  template<class...> class Op,
293  class... Args>
294 struct detector
295 {
296  using value_t = std::false_type;
297  using type = Default;
298 };
299 
300 template<class Default, template<class...> class Op, class... Args>
301 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
302 {
303  using value_t = std::true_type;
304  using type = Op<Args...>;
305 };
306 
307 template<template<class...> class Op, class... Args>
308 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
309 
310 template<template<class...> class Op, class... Args>
311 struct is_detected_lazy : is_detected<Op, Args...> { };
312 
313 template<template<class...> class Op, class... Args>
314 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
315 
316 template<class Default, template<class...> class Op, class... Args>
317 using detected_or = detector<Default, void, Op, Args...>;
318 
319 template<class Default, template<class...> class Op, class... Args>
320 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
321 
322 template<class Expected, template<class...> class Op, class... Args>
323 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
324 
325 template<class To, template<class...> class Op, class... Args>
327  std::is_convertible<detected_t<Op, Args...>, To>;
328 
329 } // namespace detail
331 
332 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
333 
334 
335 // __ _____ _____ _____
336 // __| | __| | | | JSON for Modern C++
337 // | | |__ | | | | | | version 3.12.0
338 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
339 //
340 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
341 // SPDX-FileCopyrightText: 2016 - 2021 Evan Nemerson <evan@nemerson.com>
342 // SPDX-License-Identifier: MIT
343 
344 /* Hedley - https://nemequ.github.io/hedley
345  * Created by Evan Nemerson <evan@nemerson.com>
346  */
347 
348 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
349 #if defined(JSON_HEDLEY_VERSION)
350  #undef JSON_HEDLEY_VERSION
351 #endif
352 #define JSON_HEDLEY_VERSION 15
353 
354 #if defined(JSON_HEDLEY_STRINGIFY_EX)
355  #undef JSON_HEDLEY_STRINGIFY_EX
356 #endif
357 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
358 
359 #if defined(JSON_HEDLEY_STRINGIFY)
360  #undef JSON_HEDLEY_STRINGIFY
361 #endif
362 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
363 
364 #if defined(JSON_HEDLEY_CONCAT_EX)
365  #undef JSON_HEDLEY_CONCAT_EX
366 #endif
367 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
368 
369 #if defined(JSON_HEDLEY_CONCAT)
370  #undef JSON_HEDLEY_CONCAT
371 #endif
372 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
373 
374 #if defined(JSON_HEDLEY_CONCAT3_EX)
375  #undef JSON_HEDLEY_CONCAT3_EX
376 #endif
377 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
378 
379 #if defined(JSON_HEDLEY_CONCAT3)
380  #undef JSON_HEDLEY_CONCAT3
381 #endif
382 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
383 
384 #if defined(JSON_HEDLEY_VERSION_ENCODE)
385  #undef JSON_HEDLEY_VERSION_ENCODE
386 #endif
387 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
388 
389 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
390  #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
391 #endif
392 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
393 
394 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
395  #undef JSON_HEDLEY_VERSION_DECODE_MINOR
396 #endif
397 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
398 
399 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
400  #undef JSON_HEDLEY_VERSION_DECODE_REVISION
401 #endif
402 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
403 
404 #if defined(JSON_HEDLEY_GNUC_VERSION)
405  #undef JSON_HEDLEY_GNUC_VERSION
406 #endif
407 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
408  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
409 #elif defined(__GNUC__)
410  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
411 #endif
412 
413 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
414  #undef JSON_HEDLEY_GNUC_VERSION_CHECK
415 #endif
416 #if defined(JSON_HEDLEY_GNUC_VERSION)
417  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
418 #else
419  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
420 #endif
421 
422 #if defined(JSON_HEDLEY_MSVC_VERSION)
423  #undef JSON_HEDLEY_MSVC_VERSION
424 #endif
425 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
426  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
427 #elif defined(_MSC_FULL_VER) && !defined(__ICL)
428  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
429 #elif defined(_MSC_VER) && !defined(__ICL)
430  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
431 #endif
432 
433 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
434  #undef JSON_HEDLEY_MSVC_VERSION_CHECK
435 #endif
436 #if !defined(JSON_HEDLEY_MSVC_VERSION)
437  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
438 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
439  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
440 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
441  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
442 #else
443  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
444 #endif
445 
446 #if defined(JSON_HEDLEY_INTEL_VERSION)
447  #undef JSON_HEDLEY_INTEL_VERSION
448 #endif
449 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
450  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
451 #elif defined(__INTEL_COMPILER) && !defined(__ICL)
452  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
453 #endif
454 
455 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
456  #undef JSON_HEDLEY_INTEL_VERSION_CHECK
457 #endif
458 #if defined(JSON_HEDLEY_INTEL_VERSION)
459  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
460 #else
461  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
462 #endif
463 
464 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
465  #undef JSON_HEDLEY_INTEL_CL_VERSION
466 #endif
467 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
468  #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
469 #endif
470 
471 #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
472  #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
473 #endif
474 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
475  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
476 #else
477  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
478 #endif
479 
480 #if defined(JSON_HEDLEY_PGI_VERSION)
481  #undef JSON_HEDLEY_PGI_VERSION
482 #endif
483 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
484  #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
485 #endif
486 
487 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
488  #undef JSON_HEDLEY_PGI_VERSION_CHECK
489 #endif
490 #if defined(JSON_HEDLEY_PGI_VERSION)
491  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
492 #else
493  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
494 #endif
495 
496 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
497  #undef JSON_HEDLEY_SUNPRO_VERSION
498 #endif
499 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
500  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
501 #elif defined(__SUNPRO_C)
502  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
503 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
504  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
505 #elif defined(__SUNPRO_CC)
506  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
507 #endif
508 
509 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
510  #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
511 #endif
512 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
513  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
514 #else
515  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
516 #endif
517 
518 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
519  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
520 #endif
521 #if defined(__EMSCRIPTEN__)
522  #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
523 #endif
524 
525 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
526  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
527 #endif
528 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
529  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
530 #else
531  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
532 #endif
533 
534 #if defined(JSON_HEDLEY_ARM_VERSION)
535  #undef JSON_HEDLEY_ARM_VERSION
536 #endif
537 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
538  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
539 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
540  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
541 #endif
542 
543 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
544  #undef JSON_HEDLEY_ARM_VERSION_CHECK
545 #endif
546 #if defined(JSON_HEDLEY_ARM_VERSION)
547  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
548 #else
549  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
550 #endif
551 
552 #if defined(JSON_HEDLEY_IBM_VERSION)
553  #undef JSON_HEDLEY_IBM_VERSION
554 #endif
555 #if defined(__ibmxl__)
556  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
557 #elif defined(__xlC__) && defined(__xlC_ver__)
558  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
559 #elif defined(__xlC__)
560  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
561 #endif
562 
563 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
564  #undef JSON_HEDLEY_IBM_VERSION_CHECK
565 #endif
566 #if defined(JSON_HEDLEY_IBM_VERSION)
567  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
568 #else
569  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
570 #endif
571 
572 #if defined(JSON_HEDLEY_TI_VERSION)
573  #undef JSON_HEDLEY_TI_VERSION
574 #endif
575 #if \
576  defined(__TI_COMPILER_VERSION__) && \
577  ( \
578  defined(__TMS470__) || defined(__TI_ARM__) || \
579  defined(__MSP430__) || \
580  defined(__TMS320C2000__) \
581  )
582 #if (__TI_COMPILER_VERSION__ >= 16000000)
583  #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
584 #endif
585 #endif
586 
587 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
588  #undef JSON_HEDLEY_TI_VERSION_CHECK
589 #endif
590 #if defined(JSON_HEDLEY_TI_VERSION)
591  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
592 #else
593  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
594 #endif
595 
596 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
597  #undef JSON_HEDLEY_TI_CL2000_VERSION
598 #endif
599 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
600  #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
601 #endif
602 
603 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
604  #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
605 #endif
606 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
607  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
608 #else
609  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
610 #endif
611 
612 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
613  #undef JSON_HEDLEY_TI_CL430_VERSION
614 #endif
615 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
616  #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
617 #endif
618 
619 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
620  #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
621 #endif
622 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
623  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
624 #else
625  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
626 #endif
627 
628 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
629  #undef JSON_HEDLEY_TI_ARMCL_VERSION
630 #endif
631 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
632  #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
633 #endif
634 
635 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
636  #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
637 #endif
638 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
639  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
640 #else
641  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
642 #endif
643 
644 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
645  #undef JSON_HEDLEY_TI_CL6X_VERSION
646 #endif
647 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
648  #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
649 #endif
650 
651 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
652  #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
653 #endif
654 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
655  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
656 #else
657  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
658 #endif
659 
660 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
661  #undef JSON_HEDLEY_TI_CL7X_VERSION
662 #endif
663 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
664  #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
665 #endif
666 
667 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
668  #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
669 #endif
670 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
671  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
672 #else
673  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
674 #endif
675 
676 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
677  #undef JSON_HEDLEY_TI_CLPRU_VERSION
678 #endif
679 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
680  #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
681 #endif
682 
683 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
684  #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
685 #endif
686 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
687  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
688 #else
689  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
690 #endif
691 
692 #if defined(JSON_HEDLEY_CRAY_VERSION)
693  #undef JSON_HEDLEY_CRAY_VERSION
694 #endif
695 #if defined(_CRAYC)
696  #if defined(_RELEASE_PATCHLEVEL)
697  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
698  #else
699  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
700  #endif
701 #endif
702 
703 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
704  #undef JSON_HEDLEY_CRAY_VERSION_CHECK
705 #endif
706 #if defined(JSON_HEDLEY_CRAY_VERSION)
707  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
708 #else
709  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
710 #endif
711 
712 #if defined(JSON_HEDLEY_IAR_VERSION)
713  #undef JSON_HEDLEY_IAR_VERSION
714 #endif
715 #if defined(__IAR_SYSTEMS_ICC__)
716  #if __VER__ > 1000
717  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
718  #else
719  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
720  #endif
721 #endif
722 
723 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
724  #undef JSON_HEDLEY_IAR_VERSION_CHECK
725 #endif
726 #if defined(JSON_HEDLEY_IAR_VERSION)
727  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
728 #else
729  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
730 #endif
731 
732 #if defined(JSON_HEDLEY_TINYC_VERSION)
733  #undef JSON_HEDLEY_TINYC_VERSION
734 #endif
735 #if defined(__TINYC__)
736  #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
737 #endif
738 
739 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
740  #undef JSON_HEDLEY_TINYC_VERSION_CHECK
741 #endif
742 #if defined(JSON_HEDLEY_TINYC_VERSION)
743  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
744 #else
745  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
746 #endif
747 
748 #if defined(JSON_HEDLEY_DMC_VERSION)
749  #undef JSON_HEDLEY_DMC_VERSION
750 #endif
751 #if defined(__DMC__)
752  #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
753 #endif
754 
755 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
756  #undef JSON_HEDLEY_DMC_VERSION_CHECK
757 #endif
758 #if defined(JSON_HEDLEY_DMC_VERSION)
759  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
760 #else
761  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
762 #endif
763 
764 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
765  #undef JSON_HEDLEY_COMPCERT_VERSION
766 #endif
767 #if defined(__COMPCERT_VERSION__)
768  #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
769 #endif
770 
771 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
772  #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
773 #endif
774 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
775  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
776 #else
777  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
778 #endif
779 
780 #if defined(JSON_HEDLEY_PELLES_VERSION)
781  #undef JSON_HEDLEY_PELLES_VERSION
782 #endif
783 #if defined(__POCC__)
784  #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
785 #endif
786 
787 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
788  #undef JSON_HEDLEY_PELLES_VERSION_CHECK
789 #endif
790 #if defined(JSON_HEDLEY_PELLES_VERSION)
791  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
792 #else
793  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
794 #endif
795 
796 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
797  #undef JSON_HEDLEY_MCST_LCC_VERSION
798 #endif
799 #if defined(__LCC__) && defined(__LCC_MINOR__)
800  #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
801 #endif
802 
803 #if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
804  #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
805 #endif
806 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
807  #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
808 #else
809  #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
810 #endif
811 
812 #if defined(JSON_HEDLEY_GCC_VERSION)
813  #undef JSON_HEDLEY_GCC_VERSION
814 #endif
815 #if \
816  defined(JSON_HEDLEY_GNUC_VERSION) && \
817  !defined(__clang__) && \
818  !defined(JSON_HEDLEY_INTEL_VERSION) && \
819  !defined(JSON_HEDLEY_PGI_VERSION) && \
820  !defined(JSON_HEDLEY_ARM_VERSION) && \
821  !defined(JSON_HEDLEY_CRAY_VERSION) && \
822  !defined(JSON_HEDLEY_TI_VERSION) && \
823  !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
824  !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
825  !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
826  !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
827  !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
828  !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
829  !defined(__COMPCERT__) && \
830  !defined(JSON_HEDLEY_MCST_LCC_VERSION)
831  #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
832 #endif
833 
834 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
835  #undef JSON_HEDLEY_GCC_VERSION_CHECK
836 #endif
837 #if defined(JSON_HEDLEY_GCC_VERSION)
838  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
839 #else
840  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
841 #endif
842 
843 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
844  #undef JSON_HEDLEY_HAS_ATTRIBUTE
845 #endif
846 #if \
847  defined(__has_attribute) && \
848  ( \
849  (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
850  )
851 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
852 #else
853 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
854 #endif
855 
856 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
857  #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
858 #endif
859 #if defined(__has_attribute)
860  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
861 #else
862  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
863 #endif
864 
865 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
866  #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
867 #endif
868 #if defined(__has_attribute)
869  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
870 #else
871  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
872 #endif
873 
874 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
875  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
876 #endif
877 #if \
878  defined(__has_cpp_attribute) && \
879  defined(__cplusplus) && \
880  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
881  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
882 #else
883  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
884 #endif
885 
886 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
887  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
888 #endif
889 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
890  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
891 #elif \
892  !defined(JSON_HEDLEY_PGI_VERSION) && \
893  !defined(JSON_HEDLEY_IAR_VERSION) && \
894  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
895  (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
896  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
897 #else
898  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
899 #endif
900 
901 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
902  #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
903 #endif
904 #if defined(__has_cpp_attribute) && defined(__cplusplus)
905  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
906 #else
907  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
908 #endif
909 
910 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
911  #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
912 #endif
913 #if defined(__has_cpp_attribute) && defined(__cplusplus)
914  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
915 #else
916  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
917 #endif
918 
919 #if defined(JSON_HEDLEY_HAS_BUILTIN)
920  #undef JSON_HEDLEY_HAS_BUILTIN
921 #endif
922 #if defined(__has_builtin)
923  #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
924 #else
925  #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
926 #endif
927 
928 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
929  #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
930 #endif
931 #if defined(__has_builtin)
932  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
933 #else
934  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
935 #endif
936 
937 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
938  #undef JSON_HEDLEY_GCC_HAS_BUILTIN
939 #endif
940 #if defined(__has_builtin)
941  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
942 #else
943  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
944 #endif
945 
946 #if defined(JSON_HEDLEY_HAS_FEATURE)
947  #undef JSON_HEDLEY_HAS_FEATURE
948 #endif
949 #if defined(__has_feature)
950  #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
951 #else
952  #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
953 #endif
954 
955 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
956  #undef JSON_HEDLEY_GNUC_HAS_FEATURE
957 #endif
958 #if defined(__has_feature)
959  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
960 #else
961  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
962 #endif
963 
964 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
965  #undef JSON_HEDLEY_GCC_HAS_FEATURE
966 #endif
967 #if defined(__has_feature)
968  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
969 #else
970  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
971 #endif
972 
973 #if defined(JSON_HEDLEY_HAS_EXTENSION)
974  #undef JSON_HEDLEY_HAS_EXTENSION
975 #endif
976 #if defined(__has_extension)
977  #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
978 #else
979  #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
980 #endif
981 
982 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
983  #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
984 #endif
985 #if defined(__has_extension)
986  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
987 #else
988  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
989 #endif
990 
991 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
992  #undef JSON_HEDLEY_GCC_HAS_EXTENSION
993 #endif
994 #if defined(__has_extension)
995  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
996 #else
997  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
998 #endif
999 
1000 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
1001  #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
1002 #endif
1003 #if defined(__has_declspec_attribute)
1004  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
1005 #else
1006  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
1007 #endif
1008 
1009 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
1010  #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
1011 #endif
1012 #if defined(__has_declspec_attribute)
1013  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1014 #else
1015  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1016 #endif
1017 
1018 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
1019  #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
1020 #endif
1021 #if defined(__has_declspec_attribute)
1022  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1023 #else
1024  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1025 #endif
1026 
1027 #if defined(JSON_HEDLEY_HAS_WARNING)
1028  #undef JSON_HEDLEY_HAS_WARNING
1029 #endif
1030 #if defined(__has_warning)
1031  #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
1032 #else
1033  #define JSON_HEDLEY_HAS_WARNING(warning) (0)
1034 #endif
1035 
1036 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
1037  #undef JSON_HEDLEY_GNUC_HAS_WARNING
1038 #endif
1039 #if defined(__has_warning)
1040  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1041 #else
1042  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1043 #endif
1044 
1045 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
1046  #undef JSON_HEDLEY_GCC_HAS_WARNING
1047 #endif
1048 #if defined(__has_warning)
1049  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1050 #else
1051  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1052 #endif
1053 
1054 #if \
1055  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1056  defined(__clang__) || \
1057  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1058  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1059  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1060  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1061  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1062  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1063  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1064  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1065  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1066  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
1067  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1068  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1069  JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
1070  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
1071  JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
1072  (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
1073  #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
1074 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1075  #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
1076 #else
1077  #define JSON_HEDLEY_PRAGMA(value)
1078 #endif
1079 
1080 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
1081  #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
1082 #endif
1083 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
1084  #undef JSON_HEDLEY_DIAGNOSTIC_POP
1085 #endif
1086 #if defined(__clang__)
1087  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
1088  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
1089 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1090  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1091  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1092 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1093  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
1094  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
1095 #elif \
1096  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
1097  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1098  #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
1099  #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
1100 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
1101  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
1102  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
1103 #elif \
1104  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1105  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1106  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
1107  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1108  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1109  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1110  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
1111  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
1112 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1113  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1114  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1115 #else
1116  #define JSON_HEDLEY_DIAGNOSTIC_PUSH
1117  #define JSON_HEDLEY_DIAGNOSTIC_POP
1118 #endif
1119 
1120 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
1121  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1122 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1123  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
1124 #endif
1125 #if defined(__cplusplus)
1126 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
1127 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
1128 # if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
1129 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1130  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1131  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1132  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1133  _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
1134  xpr \
1135  JSON_HEDLEY_DIAGNOSTIC_POP
1136 # else
1137 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1138  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1139  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1140  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1141  xpr \
1142  JSON_HEDLEY_DIAGNOSTIC_POP
1143 # endif
1144 # else
1145 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1146  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1147  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1148  xpr \
1149  JSON_HEDLEY_DIAGNOSTIC_POP
1150 # endif
1151 # endif
1152 #endif
1153 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1154  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
1155 #endif
1156 
1157 #if defined(JSON_HEDLEY_CONST_CAST)
1158  #undef JSON_HEDLEY_CONST_CAST
1159 #endif
1160 #if defined(__cplusplus)
1161 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1162 #elif \
1163  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1164  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1165  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1166 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1167  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1168  JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1169  ((T) (expr)); \
1170  JSON_HEDLEY_DIAGNOSTIC_POP \
1171  }))
1172 #else
1173 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1174 #endif
1175 
1176 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
1177  #undef JSON_HEDLEY_REINTERPRET_CAST
1178 #endif
1179 #if defined(__cplusplus)
1180  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1181 #else
1182  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1183 #endif
1184 
1185 #if defined(JSON_HEDLEY_STATIC_CAST)
1186  #undef JSON_HEDLEY_STATIC_CAST
1187 #endif
1188 #if defined(__cplusplus)
1189  #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1190 #else
1191  #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1192 #endif
1193 
1194 #if defined(JSON_HEDLEY_CPP_CAST)
1195  #undef JSON_HEDLEY_CPP_CAST
1196 #endif
1197 #if defined(__cplusplus)
1198 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1199 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1200  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1201  _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1202  ((T) (expr)) \
1203  JSON_HEDLEY_DIAGNOSTIC_POP
1204 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1205 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1206  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1207  _Pragma("diag_suppress=Pe137") \
1208  JSON_HEDLEY_DIAGNOSTIC_POP
1209 # else
1210 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1211 # endif
1212 #else
1213 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1214 #endif
1215 
1216 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1217  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1218 #endif
1219 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1220  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1221 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1222  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1223 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1224  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1225 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1226  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1227 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1228  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1229 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1230  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1231 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1232  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1233 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1234  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1235 #elif \
1236  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1237  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1238  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1239  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1240  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1241  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1242  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1243  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1244  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1245  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1246  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1247  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1248 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1249  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1250 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1251  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1252 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1253  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1254 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1255  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1256 #else
1257  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1258 #endif
1259 
1260 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1261  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1262 #endif
1263 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1264  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1265 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1266  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1267 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1268  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1269 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1270  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1271 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1272  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1273 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1274  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1275 #elif \
1276  JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1277  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1278  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1279  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1280  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1281 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1282  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1283 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1284  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1285 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1286  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1287 #else
1288  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1289 #endif
1290 
1291 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1292  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1293 #endif
1294 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1295  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1296 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1297  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1298 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1299  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1300 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1301  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1302 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1303  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1304 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1305  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1306 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1307  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1308 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1309  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1310 #elif \
1311  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1312  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1313  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1314  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1315 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1316  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1317 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1318  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1319 #else
1320  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1321 #endif
1322 
1323 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1324  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1325 #endif
1326 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1327  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1328 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1329  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1330 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1331  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1332 #else
1333  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1334 #endif
1335 
1336 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1337  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1338 #endif
1339 #if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1340  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1341 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1342  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1343 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1344  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1345 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1346  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1347 #else
1348  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1349 #endif
1350 
1351 #if defined(JSON_HEDLEY_DEPRECATED)
1352  #undef JSON_HEDLEY_DEPRECATED
1353 #endif
1354 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1355  #undef JSON_HEDLEY_DEPRECATED_FOR
1356 #endif
1357 #if \
1358  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1359  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1360  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1361  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1362 #elif \
1363  (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1364  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1365  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1366  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1367  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1368  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1369  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1370  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1371  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1372  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1373  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1374  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1375  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1376  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1377 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1378  #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1379  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1380 #elif \
1381  JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1382  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1383  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1384  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1385  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1386  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1387  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1388  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1389  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1390  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1391  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1392  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1393  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1394  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1395  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1396  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1397  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1398  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1399 #elif \
1400  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1401  JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1402  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1403  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1404  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1405 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1406  #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1407  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1408 #else
1409  #define JSON_HEDLEY_DEPRECATED(since)
1410  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1411 #endif
1412 
1413 #if defined(JSON_HEDLEY_UNAVAILABLE)
1414  #undef JSON_HEDLEY_UNAVAILABLE
1415 #endif
1416 #if \
1417  JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1418  JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1419  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1420  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1421  #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1422 #else
1423  #define JSON_HEDLEY_UNAVAILABLE(available_since)
1424 #endif
1425 
1426 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1427  #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1428 #endif
1429 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1430  #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1431 #endif
1432 #if \
1433  JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1434  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1435  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1436  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1437  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1438  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1439  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1440  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1441  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1442  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1443  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1444  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1445  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1446  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1447  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1448  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1449  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1450  #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1451  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1452 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1453  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1454  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1455 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1456  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1457  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1458 #elif defined(_Check_return_) /* SAL */
1459  #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1460  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1461 #else
1462  #define JSON_HEDLEY_WARN_UNUSED_RESULT
1463  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1464 #endif
1465 
1466 #if defined(JSON_HEDLEY_SENTINEL)
1467  #undef JSON_HEDLEY_SENTINEL
1468 #endif
1469 #if \
1470  JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1471  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1472  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1474  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1475  #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1476 #else
1477  #define JSON_HEDLEY_SENTINEL(position)
1478 #endif
1479 
1480 #if defined(JSON_HEDLEY_NO_RETURN)
1481  #undef JSON_HEDLEY_NO_RETURN
1482 #endif
1483 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1484  #define JSON_HEDLEY_NO_RETURN __noreturn
1485 #elif \
1486  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1487  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1488  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1489 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1490  #define JSON_HEDLEY_NO_RETURN _Noreturn
1491 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1492  #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1493 #elif \
1494  JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1495  JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1496  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1497  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1498  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1499  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1500  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1501  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1502  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1503  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1504  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1505  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1506  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1507  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1508  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1509  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1510  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1511  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1512 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1513  #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1514 #elif \
1515  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1516  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1517  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1518 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1519  #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1520 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1521  #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1522 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1523  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1524 #else
1525  #define JSON_HEDLEY_NO_RETURN
1526 #endif
1527 
1528 #if defined(JSON_HEDLEY_NO_ESCAPE)
1529  #undef JSON_HEDLEY_NO_ESCAPE
1530 #endif
1531 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1532  #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1533 #else
1534  #define JSON_HEDLEY_NO_ESCAPE
1535 #endif
1536 
1537 #if defined(JSON_HEDLEY_UNREACHABLE)
1538  #undef JSON_HEDLEY_UNREACHABLE
1539 #endif
1540 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1541  #undef JSON_HEDLEY_UNREACHABLE_RETURN
1542 #endif
1543 #if defined(JSON_HEDLEY_ASSUME)
1544  #undef JSON_HEDLEY_ASSUME
1545 #endif
1546 #if \
1547  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1548  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1549  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1550  #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1551 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1552  #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1553 #elif \
1554  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1555  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1556  #if defined(__cplusplus)
1557  #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1558  #else
1559  #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1560  #endif
1561 #endif
1562 #if \
1563  (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1564  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1565  JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1566  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1567  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1568  JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1569  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1570  #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1571 #elif defined(JSON_HEDLEY_ASSUME)
1572  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1573 #endif
1574 #if !defined(JSON_HEDLEY_ASSUME)
1575  #if defined(JSON_HEDLEY_UNREACHABLE)
1576  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1577  #else
1578  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1579  #endif
1580 #endif
1581 #if defined(JSON_HEDLEY_UNREACHABLE)
1582  #if \
1583  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1584  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1585  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1586  #else
1587  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1588  #endif
1589 #else
1590  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1591 #endif
1592 #if !defined(JSON_HEDLEY_UNREACHABLE)
1593  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1594 #endif
1595 
1597 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1598  #pragma clang diagnostic ignored "-Wpedantic"
1599 #endif
1600 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1601  #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1602 #endif
1603 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1604  #if defined(__clang__)
1605  #pragma clang diagnostic ignored "-Wvariadic-macros"
1606  #elif defined(JSON_HEDLEY_GCC_VERSION)
1607  #pragma GCC diagnostic ignored "-Wvariadic-macros"
1608  #endif
1609 #endif
1610 #if defined(JSON_HEDLEY_NON_NULL)
1611  #undef JSON_HEDLEY_NON_NULL
1612 #endif
1613 #if \
1614  JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1615  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1616  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1617  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1618  #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1619 #else
1620  #define JSON_HEDLEY_NON_NULL(...)
1621 #endif
1623 
1624 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1625  #undef JSON_HEDLEY_PRINTF_FORMAT
1626 #endif
1627 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1628  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1629 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1630  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1631 #elif \
1632  JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1633  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1634  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1635  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1636  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1637  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1638  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1639  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1640  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1641  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1642  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1643  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1644  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1645  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1646  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1647  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1648  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1649  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1650 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1651  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1652 #else
1653  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1654 #endif
1655 
1656 #if defined(JSON_HEDLEY_CONSTEXPR)
1657  #undef JSON_HEDLEY_CONSTEXPR
1658 #endif
1659 #if defined(__cplusplus)
1660  #if __cplusplus >= 201103L
1661  #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1662  #endif
1663 #endif
1664 #if !defined(JSON_HEDLEY_CONSTEXPR)
1665  #define JSON_HEDLEY_CONSTEXPR
1666 #endif
1667 
1668 #if defined(JSON_HEDLEY_PREDICT)
1669  #undef JSON_HEDLEY_PREDICT
1670 #endif
1671 #if defined(JSON_HEDLEY_LIKELY)
1672  #undef JSON_HEDLEY_LIKELY
1673 #endif
1674 #if defined(JSON_HEDLEY_UNLIKELY)
1675  #undef JSON_HEDLEY_UNLIKELY
1676 #endif
1677 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1678  #undef JSON_HEDLEY_UNPREDICTABLE
1679 #endif
1680 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1681  #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1682 #endif
1683 #if \
1684  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1685  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1686  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1687 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1688 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1689 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1690 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1691 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1692 #elif \
1693  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1694  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1695  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1696  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1697  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1698  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1699  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1700  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1701  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1702  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1703  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1704  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1705  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1706  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1707  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1708  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1709 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1710  (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1711 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1712  (__extension__ ({ \
1713  double hedley_probability_ = (probability); \
1714  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1715  }))
1716 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1717  (__extension__ ({ \
1718  double hedley_probability_ = (probability); \
1719  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1720  }))
1721 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1722 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1723 #else
1724 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1725 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1726 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1727 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1728 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1729 #endif
1730 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1731  #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1732 #endif
1733 
1734 #if defined(JSON_HEDLEY_MALLOC)
1735  #undef JSON_HEDLEY_MALLOC
1736 #endif
1737 #if \
1738  JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1739  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1740  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1741  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1742  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1743  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1744  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1745  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1746  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1747  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1748  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1749  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1750  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1751  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1752  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1753  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1754  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1755  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1756  #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1757 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1758  #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1759 #elif \
1760  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1761  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1762  #define JSON_HEDLEY_MALLOC __declspec(restrict)
1763 #else
1764  #define JSON_HEDLEY_MALLOC
1765 #endif
1766 
1767 #if defined(JSON_HEDLEY_PURE)
1768  #undef JSON_HEDLEY_PURE
1769 #endif
1770 #if \
1771  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1772  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1773  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1774  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1775  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1776  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1777  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1778  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1779  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1780  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1781  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1782  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1783  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1784  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1785  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1786  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1787  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1788  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1789  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1790 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1791 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1792 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1793 #elif defined(__cplusplus) && \
1794  ( \
1795  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1796  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1797  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1798  )
1799 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1800 #else
1801 # define JSON_HEDLEY_PURE
1802 #endif
1803 
1804 #if defined(JSON_HEDLEY_CONST)
1805  #undef JSON_HEDLEY_CONST
1806 #endif
1807 #if \
1808  JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1809  JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1810  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1811  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1812  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1813  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1814  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1815  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1816  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1817  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1818  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1819  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1820  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1821  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1822  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1823  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1824  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1825  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1826  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1827  #define JSON_HEDLEY_CONST __attribute__((__const__))
1828 #elif \
1829  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1830  #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1831 #else
1832  #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1833 #endif
1834 
1835 #if defined(JSON_HEDLEY_RESTRICT)
1836  #undef JSON_HEDLEY_RESTRICT
1837 #endif
1838 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1839  #define JSON_HEDLEY_RESTRICT restrict
1840 #elif \
1841  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1842  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1843  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1844  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1845  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1846  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1847  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1848  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1849  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1850  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1851  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1852  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1853  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1854  defined(__clang__) || \
1855  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1856  #define JSON_HEDLEY_RESTRICT __restrict
1857 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1858  #define JSON_HEDLEY_RESTRICT _Restrict
1859 #else
1860  #define JSON_HEDLEY_RESTRICT
1861 #endif
1862 
1863 #if defined(JSON_HEDLEY_INLINE)
1864  #undef JSON_HEDLEY_INLINE
1865 #endif
1866 #if \
1867  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1868  (defined(__cplusplus) && (__cplusplus >= 199711L))
1869  #define JSON_HEDLEY_INLINE inline
1870 #elif \
1871  defined(JSON_HEDLEY_GCC_VERSION) || \
1872  JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1873  #define JSON_HEDLEY_INLINE __inline__
1874 #elif \
1875  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1876  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1877  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1878  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1879  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1880  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1881  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1882  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1883  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1884  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1885  #define JSON_HEDLEY_INLINE __inline
1886 #else
1887  #define JSON_HEDLEY_INLINE
1888 #endif
1889 
1890 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1891  #undef JSON_HEDLEY_ALWAYS_INLINE
1892 #endif
1893 #if \
1894  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1895  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1896  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1897  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1898  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1899  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1900  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1901  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1902  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1903  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1904  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1905  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1906  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1907  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1908  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1909  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1910  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1911  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1912  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1913 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1914 #elif \
1915  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1916  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1917 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1918 #elif defined(__cplusplus) && \
1919  ( \
1920  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1921  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1922  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1923  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1924  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1925  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1926  )
1927 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1928 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1929 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1930 #else
1931 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1932 #endif
1933 
1934 #if defined(JSON_HEDLEY_NEVER_INLINE)
1935  #undef JSON_HEDLEY_NEVER_INLINE
1936 #endif
1937 #if \
1938  JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1939  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1940  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1941  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1942  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1943  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1944  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1945  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1946  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1947  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1948  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1949  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1950  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1951  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1952  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1953  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1954  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1955  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1956  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1957  #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1958 #elif \
1959  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1960  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1961  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1962 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1963  #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1964 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1965  #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1966 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1967  #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1968 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1969  #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1970 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1971  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1972 #else
1973  #define JSON_HEDLEY_NEVER_INLINE
1974 #endif
1975 
1976 #if defined(JSON_HEDLEY_PRIVATE)
1977  #undef JSON_HEDLEY_PRIVATE
1978 #endif
1979 #if defined(JSON_HEDLEY_PUBLIC)
1980  #undef JSON_HEDLEY_PUBLIC
1981 #endif
1982 #if defined(JSON_HEDLEY_IMPORT)
1983  #undef JSON_HEDLEY_IMPORT
1984 #endif
1985 #if defined(_WIN32) || defined(__CYGWIN__)
1986 # define JSON_HEDLEY_PRIVATE
1987 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1988 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1989 #else
1990 # if \
1991  JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1992  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1993  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1994  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1995  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1996  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1997  ( \
1998  defined(__TI_EABI__) && \
1999  ( \
2000  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
2001  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
2002  ) \
2003  ) || \
2004  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2005 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
2006 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
2007 # else
2008 # define JSON_HEDLEY_PRIVATE
2009 # define JSON_HEDLEY_PUBLIC
2010 # endif
2011 # define JSON_HEDLEY_IMPORT extern
2012 #endif
2013 
2014 #if defined(JSON_HEDLEY_NO_THROW)
2015  #undef JSON_HEDLEY_NO_THROW
2016 #endif
2017 #if \
2018  JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
2019  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
2020  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2021  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2022  #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
2023 #elif \
2024  JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
2025  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
2026  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
2027  #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
2028 #else
2029  #define JSON_HEDLEY_NO_THROW
2030 #endif
2031 
2032 #if defined(JSON_HEDLEY_FALL_THROUGH)
2033  #undef JSON_HEDLEY_FALL_THROUGH
2034 #endif
2035 #if \
2036  JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
2037  JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
2038  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2039  #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
2040 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
2041  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
2042 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
2043  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
2044 #elif defined(__fallthrough) /* SAL */
2045  #define JSON_HEDLEY_FALL_THROUGH __fallthrough
2046 #else
2047  #define JSON_HEDLEY_FALL_THROUGH
2048 #endif
2049 
2050 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
2051  #undef JSON_HEDLEY_RETURNS_NON_NULL
2052 #endif
2053 #if \
2054  JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
2055  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2056  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2057  #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
2058 #elif defined(_Ret_notnull_) /* SAL */
2059  #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
2060 #else
2061  #define JSON_HEDLEY_RETURNS_NON_NULL
2062 #endif
2063 
2064 #if defined(JSON_HEDLEY_ARRAY_PARAM)
2065  #undef JSON_HEDLEY_ARRAY_PARAM
2066 #endif
2067 #if \
2068  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
2069  !defined(__STDC_NO_VLA__) && \
2070  !defined(__cplusplus) && \
2071  !defined(JSON_HEDLEY_PGI_VERSION) && \
2072  !defined(JSON_HEDLEY_TINYC_VERSION)
2073  #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
2074 #else
2075  #define JSON_HEDLEY_ARRAY_PARAM(name)
2076 #endif
2077 
2078 #if defined(JSON_HEDLEY_IS_CONSTANT)
2079  #undef JSON_HEDLEY_IS_CONSTANT
2080 #endif
2081 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
2082  #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
2083 #endif
2084 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
2085  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
2086 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2087  #undef JSON_HEDLEY_IS_CONSTEXPR_
2088 #endif
2089 #if \
2090  JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
2091  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2092  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2093  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
2094  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2095  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2096  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
2097  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
2098  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2099  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2100  #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
2101 #endif
2102 #if !defined(__cplusplus)
2103 # if \
2104  JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
2105  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2106  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2107  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2108  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2109  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
2110  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
2111 #if defined(__INTPTR_TYPE__)
2112  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
2113 #else
2114  #include <stdint.h>
2115  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
2116 #endif
2117 # elif \
2118  ( \
2119  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
2120  !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
2121  !defined(JSON_HEDLEY_PGI_VERSION) && \
2122  !defined(JSON_HEDLEY_IAR_VERSION)) || \
2123  (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
2124  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2125  JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
2126  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
2127  JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
2128 #if defined(__INTPTR_TYPE__)
2129  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
2130 #else
2131  #include <stdint.h>
2132  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
2133 #endif
2134 # elif \
2135  defined(JSON_HEDLEY_GCC_VERSION) || \
2136  defined(JSON_HEDLEY_INTEL_VERSION) || \
2137  defined(JSON_HEDLEY_TINYC_VERSION) || \
2138  defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
2139  JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
2140  defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
2141  defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
2142  defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
2143  defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
2144  defined(__clang__)
2145 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
2146  sizeof(void) != \
2147  sizeof(*( \
2148  1 ? \
2149  ((void*) ((expr) * 0L) ) : \
2150 ((struct { char v[sizeof(void) * 2]; } *) 1) \
2151  ) \
2152  ) \
2153  )
2154 # endif
2155 #endif
2156 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2157  #if !defined(JSON_HEDLEY_IS_CONSTANT)
2158  #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2159  #endif
2160  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2161 #else
2162  #if !defined(JSON_HEDLEY_IS_CONSTANT)
2163  #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2164  #endif
2165  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2166 #endif
2167 
2168 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2169  #undef JSON_HEDLEY_BEGIN_C_DECLS
2170 #endif
2171 #if defined(JSON_HEDLEY_END_C_DECLS)
2172  #undef JSON_HEDLEY_END_C_DECLS
2173 #endif
2174 #if defined(JSON_HEDLEY_C_DECL)
2175  #undef JSON_HEDLEY_C_DECL
2176 #endif
2177 #if defined(__cplusplus)
2178  #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2179  #define JSON_HEDLEY_END_C_DECLS }
2180  #define JSON_HEDLEY_C_DECL extern "C"
2181 #else
2182  #define JSON_HEDLEY_BEGIN_C_DECLS
2183  #define JSON_HEDLEY_END_C_DECLS
2184  #define JSON_HEDLEY_C_DECL
2185 #endif
2186 
2187 #if defined(JSON_HEDLEY_STATIC_ASSERT)
2188  #undef JSON_HEDLEY_STATIC_ASSERT
2189 #endif
2190 #if \
2191  !defined(__cplusplus) && ( \
2192  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2193  (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2194  JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2195  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2196  defined(_Static_assert) \
2197  )
2198 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2199 #elif \
2200  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2201  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2202  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2203 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2204 #else
2205 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2206 #endif
2207 
2208 #if defined(JSON_HEDLEY_NULL)
2209  #undef JSON_HEDLEY_NULL
2210 #endif
2211 #if defined(__cplusplus)
2212  #if __cplusplus >= 201103L
2213  #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2214  #elif defined(NULL)
2215  #define JSON_HEDLEY_NULL NULL
2216  #else
2217  #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2218  #endif
2219 #elif defined(NULL)
2220  #define JSON_HEDLEY_NULL NULL
2221 #else
2222  #define JSON_HEDLEY_NULL ((void*) 0)
2223 #endif
2224 
2225 #if defined(JSON_HEDLEY_MESSAGE)
2226  #undef JSON_HEDLEY_MESSAGE
2227 #endif
2228 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2229 # define JSON_HEDLEY_MESSAGE(msg) \
2230  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2231  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2232  JSON_HEDLEY_PRAGMA(message msg) \
2233  JSON_HEDLEY_DIAGNOSTIC_POP
2234 #elif \
2235  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2236  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2237 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2238 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2239 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2240 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2241 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2242 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2243 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2244 #else
2245 # define JSON_HEDLEY_MESSAGE(msg)
2246 #endif
2247 
2248 #if defined(JSON_HEDLEY_WARNING)
2249  #undef JSON_HEDLEY_WARNING
2250 #endif
2251 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2252 # define JSON_HEDLEY_WARNING(msg) \
2253  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2254  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2255  JSON_HEDLEY_PRAGMA(clang warning msg) \
2256  JSON_HEDLEY_DIAGNOSTIC_POP
2257 #elif \
2258  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2259  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2260  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2261 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2262 #elif \
2263  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2264  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2265 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2266 #else
2267 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2268 #endif
2269 
2270 #if defined(JSON_HEDLEY_REQUIRE)
2271  #undef JSON_HEDLEY_REQUIRE
2272 #endif
2273 #if defined(JSON_HEDLEY_REQUIRE_MSG)
2274  #undef JSON_HEDLEY_REQUIRE_MSG
2275 #endif
2276 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2277 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2278 # define JSON_HEDLEY_REQUIRE(expr) \
2279  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2280  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2281  __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2282  JSON_HEDLEY_DIAGNOSTIC_POP
2283 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2284  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2285  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2286  __attribute__((diagnose_if(!(expr), msg, "error"))) \
2287  JSON_HEDLEY_DIAGNOSTIC_POP
2288 # else
2289 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2290 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2291 # endif
2292 #else
2293 # define JSON_HEDLEY_REQUIRE(expr)
2294 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2295 #endif
2296 
2297 #if defined(JSON_HEDLEY_FLAGS)
2298  #undef JSON_HEDLEY_FLAGS
2299 #endif
2300 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2301  #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2302 #else
2303  #define JSON_HEDLEY_FLAGS
2304 #endif
2305 
2306 #if defined(JSON_HEDLEY_FLAGS_CAST)
2307  #undef JSON_HEDLEY_FLAGS_CAST
2308 #endif
2309 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2310 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2311  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2312  _Pragma("warning(disable:188)") \
2313  ((T) (expr)); \
2314  JSON_HEDLEY_DIAGNOSTIC_POP \
2315  }))
2316 #else
2317 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2318 #endif
2319 
2320 #if defined(JSON_HEDLEY_EMPTY_BASES)
2321  #undef JSON_HEDLEY_EMPTY_BASES
2322 #endif
2323 #if \
2324  (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2325  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2326  #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2327 #else
2328  #define JSON_HEDLEY_EMPTY_BASES
2329 #endif
2330 
2331 /* Remaining macros are deprecated. */
2332 
2333 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2334  #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2335 #endif
2336 #if defined(__clang__)
2337  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2338 #else
2339  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2340 #endif
2341 
2342 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2343  #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2344 #endif
2345 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2346 
2347 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2348  #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2349 #endif
2350 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2351 
2352 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2353  #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2354 #endif
2355 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2356 
2357 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2358  #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2359 #endif
2360 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2361 
2362 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2363  #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2364 #endif
2365 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2366 
2367 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2368  #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2369 #endif
2370 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2371 
2372 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2373  #undef JSON_HEDLEY_CLANG_HAS_WARNING
2374 #endif
2375 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2376 
2377 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2378 
2379 
2380 // This file contains all internal macro definitions (except those affecting ABI)
2381 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2382 
2383 // #include <nlohmann/detail/abi_macros.hpp>
2384 
2385 
2386 // exclude unsupported compilers
2387 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2388  #if defined(__clang__)
2389  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2390  #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2391  #endif
2392  #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2393  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2394  #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2395  #endif
2396  #endif
2397 #endif
2398 
2399 // C++ language standard detection
2400 // if the user manually specified the used c++ version this is skipped
2401 #if !defined(JSON_HAS_CPP_23) && !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2402  #if (defined(__cplusplus) && __cplusplus > 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG > 202002L)
2403  #define JSON_HAS_CPP_23
2404  #define JSON_HAS_CPP_20
2405  #define JSON_HAS_CPP_17
2406  #define JSON_HAS_CPP_14
2407  #elif (defined(__cplusplus) && __cplusplus > 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG > 201703L)
2408  #define JSON_HAS_CPP_20
2409  #define JSON_HAS_CPP_17
2410  #define JSON_HAS_CPP_14
2411  #elif (defined(__cplusplus) && __cplusplus > 201402L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2412  #define JSON_HAS_CPP_17
2413  #define JSON_HAS_CPP_14
2414  #elif (defined(__cplusplus) && __cplusplus > 201103L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2415  #define JSON_HAS_CPP_14
2416  #endif
2417  // the cpp 11 flag is always specified because it is the minimal required version
2418  #define JSON_HAS_CPP_11
2419 #endif
2420 
2421 #ifdef __has_include
2422  #if __has_include(<version>)
2423  #include <version>
2424  #endif
2425 #endif
2426 
2427 #if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2428  #ifdef JSON_HAS_CPP_17
2429  #if defined(__cpp_lib_filesystem)
2430  #define JSON_HAS_FILESYSTEM 1
2431  #elif defined(__cpp_lib_experimental_filesystem)
2432  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2433  #elif !defined(__has_include)
2434  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2435  #elif __has_include(<filesystem>)
2436  #define JSON_HAS_FILESYSTEM 1
2437  #elif __has_include(<experimental/filesystem>)
2438  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2439  #endif
2440 
2441  // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2442  #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2443  #undef JSON_HAS_FILESYSTEM
2444  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2445  #endif
2446 
2447  // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2448  #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2449  #undef JSON_HAS_FILESYSTEM
2450  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2451  #endif
2452 
2453  // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2454  #if defined(__clang_major__) && __clang_major__ < 7
2455  #undef JSON_HAS_FILESYSTEM
2456  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2457  #endif
2458 
2459  // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2460  #if defined(_MSC_VER) && _MSC_VER < 1914
2461  #undef JSON_HAS_FILESYSTEM
2462  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2463  #endif
2464 
2465  // no filesystem support before iOS 13
2466  #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2467  #undef JSON_HAS_FILESYSTEM
2468  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2469  #endif
2470 
2471  // no filesystem support before macOS Catalina
2472  #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2473  #undef JSON_HAS_FILESYSTEM
2474  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2475  #endif
2476  #endif
2477 #endif
2478 
2479 #ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2480  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2481 #endif
2482 
2483 #ifndef JSON_HAS_FILESYSTEM
2484  #define JSON_HAS_FILESYSTEM 0
2485 #endif
2486 
2487 #ifndef JSON_HAS_THREE_WAY_COMPARISON
2488  #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \
2489  && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
2490  #define JSON_HAS_THREE_WAY_COMPARISON 1
2491  #else
2492  #define JSON_HAS_THREE_WAY_COMPARISON 0
2493  #endif
2494 #endif
2495 
2496 #ifndef JSON_HAS_RANGES
2497  // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error
2498  #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427
2499  #define JSON_HAS_RANGES 0
2500  #elif defined(__cpp_lib_ranges)
2501  #define JSON_HAS_RANGES 1
2502  #else
2503  #define JSON_HAS_RANGES 0
2504  #endif
2505 #endif
2506 
2507 #ifndef JSON_HAS_STATIC_RTTI
2508  #if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0
2509  #define JSON_HAS_STATIC_RTTI 1
2510  #else
2511  #define JSON_HAS_STATIC_RTTI 0
2512  #endif
2513 #endif
2514 
2515 #ifdef JSON_HAS_CPP_17
2516  #define JSON_INLINE_VARIABLE inline
2517 #else
2518  #define JSON_INLINE_VARIABLE
2519 #endif
2520 
2521 #if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2522  #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2523 #else
2524  #define JSON_NO_UNIQUE_ADDRESS
2525 #endif
2526 
2527 // disable documentation warnings on clang
2528 #if defined(__clang__)
2529  #pragma clang diagnostic push
2530  #pragma clang diagnostic ignored "-Wdocumentation"
2531  #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2532 #endif
2533 
2534 // allow disabling exceptions
2535 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2536  #define JSON_THROW(exception) throw exception
2537  #define JSON_TRY try
2538  #define JSON_CATCH(exception) catch(exception)
2539  #define JSON_INTERNAL_CATCH(exception) catch(exception)
2540 #else
2541  #include <cstdlib>
2542  #define JSON_THROW(exception) std::abort()
2543  #define JSON_TRY if(true)
2544  #define JSON_CATCH(exception) if(false)
2545  #define JSON_INTERNAL_CATCH(exception) if(false)
2546 #endif
2547 
2548 // override exception macros
2549 #if defined(JSON_THROW_USER)
2550  #undef JSON_THROW
2551  #define JSON_THROW JSON_THROW_USER
2552 #endif
2553 #if defined(JSON_TRY_USER)
2554  #undef JSON_TRY
2555  #define JSON_TRY JSON_TRY_USER
2556 #endif
2557 #if defined(JSON_CATCH_USER)
2558  #undef JSON_CATCH
2559  #define JSON_CATCH JSON_CATCH_USER
2560  #undef JSON_INTERNAL_CATCH
2561  #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2562 #endif
2563 #if defined(JSON_INTERNAL_CATCH_USER)
2564  #undef JSON_INTERNAL_CATCH
2565  #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2566 #endif
2567 
2568 // allow overriding assert
2569 #if !defined(JSON_ASSERT)
2570  #include <cassert> // assert
2571  #define JSON_ASSERT(x) assert(x)
2572 #endif
2573 
2574 // allow to access some private functions (needed by the test suite)
2575 #if defined(JSON_TESTS_PRIVATE)
2576  #define JSON_PRIVATE_UNLESS_TESTED public
2577 #else
2578  #define JSON_PRIVATE_UNLESS_TESTED private
2579 #endif
2580 
2586 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2587  template<typename BasicJsonType> \
2588  inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2589  { \
2590  /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
2591  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2592  /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
2593  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2594  auto it = std::find_if(std::begin(m), std::end(m), \
2595  [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2596  { \
2597  return ej_pair.first == e; \
2598  }); \
2599  j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2600  } \
2601  template<typename BasicJsonType> \
2602  inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2603  { \
2604  /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \
2605  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2606  /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on <array> */ \
2607  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2608  auto it = std::find_if(std::begin(m), std::end(m), \
2609  [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2610  { \
2611  return ej_pair.second == j; \
2612  }); \
2613  e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2614  }
2615 
2616 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2617 // may be removed in the future once the class is split.
2618 
2619 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2620  template<template<typename, typename, typename...> class ObjectType, \
2621  template<typename, typename...> class ArrayType, \
2622  class StringType, class BooleanType, class NumberIntegerType, \
2623  class NumberUnsignedType, class NumberFloatType, \
2624  template<typename> class AllocatorType, \
2625  template<typename, typename = void> class JSONSerializer, \
2626  class BinaryType, \
2627  class CustomBaseClass>
2628 
2629 #define NLOHMANN_BASIC_JSON_TPL \
2630  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2631  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2632  AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>
2633 
2634 // Macros to simplify conversion from/to types
2635 
2636 #define NLOHMANN_JSON_EXPAND( x ) x
2637 #define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2638 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2639  NLOHMANN_JSON_PASTE64, \
2640  NLOHMANN_JSON_PASTE63, \
2641  NLOHMANN_JSON_PASTE62, \
2642  NLOHMANN_JSON_PASTE61, \
2643  NLOHMANN_JSON_PASTE60, \
2644  NLOHMANN_JSON_PASTE59, \
2645  NLOHMANN_JSON_PASTE58, \
2646  NLOHMANN_JSON_PASTE57, \
2647  NLOHMANN_JSON_PASTE56, \
2648  NLOHMANN_JSON_PASTE55, \
2649  NLOHMANN_JSON_PASTE54, \
2650  NLOHMANN_JSON_PASTE53, \
2651  NLOHMANN_JSON_PASTE52, \
2652  NLOHMANN_JSON_PASTE51, \
2653  NLOHMANN_JSON_PASTE50, \
2654  NLOHMANN_JSON_PASTE49, \
2655  NLOHMANN_JSON_PASTE48, \
2656  NLOHMANN_JSON_PASTE47, \
2657  NLOHMANN_JSON_PASTE46, \
2658  NLOHMANN_JSON_PASTE45, \
2659  NLOHMANN_JSON_PASTE44, \
2660  NLOHMANN_JSON_PASTE43, \
2661  NLOHMANN_JSON_PASTE42, \
2662  NLOHMANN_JSON_PASTE41, \
2663  NLOHMANN_JSON_PASTE40, \
2664  NLOHMANN_JSON_PASTE39, \
2665  NLOHMANN_JSON_PASTE38, \
2666  NLOHMANN_JSON_PASTE37, \
2667  NLOHMANN_JSON_PASTE36, \
2668  NLOHMANN_JSON_PASTE35, \
2669  NLOHMANN_JSON_PASTE34, \
2670  NLOHMANN_JSON_PASTE33, \
2671  NLOHMANN_JSON_PASTE32, \
2672  NLOHMANN_JSON_PASTE31, \
2673  NLOHMANN_JSON_PASTE30, \
2674  NLOHMANN_JSON_PASTE29, \
2675  NLOHMANN_JSON_PASTE28, \
2676  NLOHMANN_JSON_PASTE27, \
2677  NLOHMANN_JSON_PASTE26, \
2678  NLOHMANN_JSON_PASTE25, \
2679  NLOHMANN_JSON_PASTE24, \
2680  NLOHMANN_JSON_PASTE23, \
2681  NLOHMANN_JSON_PASTE22, \
2682  NLOHMANN_JSON_PASTE21, \
2683  NLOHMANN_JSON_PASTE20, \
2684  NLOHMANN_JSON_PASTE19, \
2685  NLOHMANN_JSON_PASTE18, \
2686  NLOHMANN_JSON_PASTE17, \
2687  NLOHMANN_JSON_PASTE16, \
2688  NLOHMANN_JSON_PASTE15, \
2689  NLOHMANN_JSON_PASTE14, \
2690  NLOHMANN_JSON_PASTE13, \
2691  NLOHMANN_JSON_PASTE12, \
2692  NLOHMANN_JSON_PASTE11, \
2693  NLOHMANN_JSON_PASTE10, \
2694  NLOHMANN_JSON_PASTE9, \
2695  NLOHMANN_JSON_PASTE8, \
2696  NLOHMANN_JSON_PASTE7, \
2697  NLOHMANN_JSON_PASTE6, \
2698  NLOHMANN_JSON_PASTE5, \
2699  NLOHMANN_JSON_PASTE4, \
2700  NLOHMANN_JSON_PASTE3, \
2701  NLOHMANN_JSON_PASTE2, \
2702  NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2703 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2704 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2705 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2706 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2707 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2708 #define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2709 #define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2710 #define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2711 #define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2712 #define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2713 #define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2714 #define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2715 #define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2716 #define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2717 #define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2718 #define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2719 #define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2720 #define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2721 #define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2722 #define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2723 #define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2724 #define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2725 #define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2726 #define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2727 #define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2728 #define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2729 #define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2730 #define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2731 #define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2732 #define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2733 #define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2734 #define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2735 #define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2736 #define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2737 #define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2738 #define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2739 #define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2740 #define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2741 #define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2742 #define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2743 #define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2744 #define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2745 #define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2746 #define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2747 #define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2748 #define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2749 #define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2750 #define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2751 #define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2752 #define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2753 #define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2754 #define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2755 #define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2756 #define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2757 #define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2758 #define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2759 #define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2760 #define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2761 #define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2762 #define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2763 #define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2764 #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2765 #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2766 
2767 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2768 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2769 #define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = !nlohmann_json_j.is_null() ? nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1) : nlohmann_json_default_obj.v1;
2770 
2777 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2778  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2779  friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2780  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2781  friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2782 
2789 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2790  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2791  friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2792  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2793  friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2794 
2801 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
2802  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2803  friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
2804 
2811 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2812  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2813  void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2814  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2815  void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2816 
2823 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2824  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2825  void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2826  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2827  void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2828 
2835 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
2836  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2837  void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
2838 
2845 #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Type, BaseType, ...) \
2846  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2847  friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2848  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2849  friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2850 
2857 #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \
2858  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2859  friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2860  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2861  friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2862 
2869 #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \
2870  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2871  friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
2872 
2879 #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(Type, BaseType, ...) \
2880  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2881  void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2882  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2883  void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2884 
2891 #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \
2892  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2893  void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2894  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2895  void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast<BaseType&>(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2896 
2903 #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \
2904  template<typename BasicJsonType, nlohmann::detail::enable_if_t<nlohmann::detail::is_basic_json<BasicJsonType>::value, int> = 0> \
2905  void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast<const BaseType &>(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) }
2906 
2907 // inspired from https://stackoverflow.com/a/26745591
2908 // allows calling any std function as if (e.g., with begin):
2909 // using std::begin; begin(x);
2910 //
2911 // it allows using the detected idiom to retrieve the return type
2912 // of such an expression
2913 #define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2914  namespace detail { \
2915  using std::std_name; \
2916  \
2917  template<typename... T> \
2918  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2919  } \
2920  \
2921  namespace detail2 { \
2922  struct std_name##_tag \
2923  { \
2924  }; \
2925  \
2926  template<typename... T> \
2927  std_name##_tag std_name(T&&...); \
2928  \
2929  template<typename... T> \
2930  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2931  \
2932  template<typename... T> \
2933  struct would_call_std_##std_name \
2934  { \
2935  static constexpr auto const value = ::nlohmann::detail:: \
2936  is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2937  }; \
2938  } /* namespace detail2 */ \
2939  \
2940  template<typename... T> \
2941  struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2942  { \
2943  }
2944 
2945 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2946  #define JSON_USE_IMPLICIT_CONVERSIONS 1
2947 #endif
2948 
2949 #if JSON_USE_IMPLICIT_CONVERSIONS
2950  #define JSON_EXPLICIT
2951 #else
2952  #define JSON_EXPLICIT explicit
2953 #endif
2954 
2955 #ifndef JSON_DISABLE_ENUM_SERIALIZATION
2956  #define JSON_DISABLE_ENUM_SERIALIZATION 0
2957 #endif
2958 
2959 #ifndef JSON_USE_GLOBAL_UDLS
2960  #define JSON_USE_GLOBAL_UDLS 1
2961 #endif
2962 
2963 #if JSON_HAS_THREE_WAY_COMPARISON
2964  #include <compare> // partial_ordering
2965 #endif
2966 
2968 namespace detail
2969 {
2970 
2972 // JSON type enumeration //
2974 
2999 enum class value_t : std::uint8_t
3000 {
3001  null,
3002  object,
3003  array,
3004  string,
3005  boolean,
3006  number_integer,
3007  number_unsigned,
3008  number_float,
3009  binary,
3010  discarded
3011 };
3012 
3026 #if JSON_HAS_THREE_WAY_COMPARISON
3027  inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
3028 #else
3029  inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3030 #endif
3031 {
3032  static constexpr std::array<std::uint8_t, 9> order = {{
3033  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
3034  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
3035  6 /* binary */
3036  }
3037  };
3038 
3039  const auto l_index = static_cast<std::size_t>(lhs);
3040  const auto r_index = static_cast<std::size_t>(rhs);
3041 #if JSON_HAS_THREE_WAY_COMPARISON
3042  if (l_index < order.size() && r_index < order.size())
3043  {
3044  return order[l_index] <=> order[r_index]; // *NOPAD*
3045  }
3046  return std::partial_ordering::unordered;
3047 #else
3048  return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
3049 #endif
3050 }
3051 
3052 // GCC selects the built-in operator< over an operator rewritten from
3053 // a user-defined spaceship operator
3054 // Clang, MSVC, and ICC select the rewritten candidate
3055 // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
3056 #if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
3057 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3058 {
3059  return std::is_lt(lhs <=> rhs); // *NOPAD*
3060 }
3061 #endif
3062 
3063 } // namespace detail
3065 
3066 // #include <nlohmann/detail/string_escape.hpp>
3067 // __ _____ _____ _____
3068 // __| | __| | | | JSON for Modern C++
3069 // | | |__ | | | | | | version 3.12.0
3070 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3071 //
3072 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3073 // SPDX-License-Identifier: MIT
3074 
3075 
3076 
3077 // #include <nlohmann/detail/abi_macros.hpp>
3078 
3079 
3081 namespace detail
3082 {
3083 
3097 template<typename StringType>
3098 inline void replace_substring(StringType& s, const StringType& f,
3099  const StringType& t)
3100 {
3101  JSON_ASSERT(!f.empty());
3102  for (auto pos = s.find(f); // find first occurrence of f
3103  pos != StringType::npos; // make sure f was found
3104  s.replace(pos, f.size(), t), // replace with t, and
3105  pos = s.find(f, pos + t.size())) // find next occurrence of f
3106  {}
3107 }
3108 
3116 template<typename StringType>
3117 inline StringType escape(StringType s)
3118 {
3119  replace_substring(s, StringType{"~"}, StringType{"~0"});
3120  replace_substring(s, StringType{"/"}, StringType{"~1"});
3121  return s;
3122 }
3123 
3131 template<typename StringType>
3132 static void unescape(StringType& s)
3133 {
3134  replace_substring(s, StringType{"~1"}, StringType{"/"});
3135  replace_substring(s, StringType{"~0"}, StringType{"~"});
3136 }
3137 
3138 } // namespace detail
3140 
3141 // #include <nlohmann/detail/input/position_t.hpp>
3142 // __ _____ _____ _____
3143 // __| | __| | | | JSON for Modern C++
3144 // | | |__ | | | | | | version 3.12.0
3145 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3146 //
3147 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3148 // SPDX-License-Identifier: MIT
3149 
3150 
3151 
3152 #include <cstddef> // size_t
3153 
3154 // #include <nlohmann/detail/abi_macros.hpp>
3155 
3156 
3158 namespace detail
3159 {
3160 
3163 {
3165  std::size_t chars_read_total = 0;
3167  std::size_t chars_read_current_line = 0;
3169  std::size_t lines_read = 0;
3170 
3172  constexpr operator size_t() const
3173  {
3174  return chars_read_total;
3175  }
3176 };
3177 
3178 } // namespace detail
3180 
3181 // #include <nlohmann/detail/macro_scope.hpp>
3182 
3183 // #include <nlohmann/detail/meta/cpp_future.hpp>
3184 // __ _____ _____ _____
3185 // __| | __| | | | JSON for Modern C++
3186 // | | |__ | | | | | | version 3.12.0
3187 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3188 //
3189 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3190 // SPDX-FileCopyrightText: 2018 The Abseil Authors
3191 // SPDX-License-Identifier: MIT
3192 
3193 
3194 
3195 #include <array> // array
3196 #include <cstddef> // size_t
3197 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3198 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3199 
3200 // #include <nlohmann/detail/macro_scope.hpp>
3201 
3202 
3204 namespace detail
3205 {
3206 
3207 template<typename T>
3208 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3209 
3210 #ifdef JSON_HAS_CPP_14
3211 
3212 // the following utilities are natively available in C++14
3213 using std::enable_if_t;
3214 using std::index_sequence;
3217 
3218 #else
3219 
3220 // alias templates to reduce boilerplate
3221 template<bool B, typename T = void>
3222 using enable_if_t = typename std::enable_if<B, T>::type;
3223 
3224 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3225 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3226 
3228 
3229 // integer_sequence
3230 //
3231 // Class template representing a compile-time integer sequence. An instantiation
3232 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3233 // type through its template arguments (which is a common need when
3234 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3235 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3236 //
3237 // Example:
3238 //
3239 // template< class T, T... Ints >
3240 // void user_function(integer_sequence<T, Ints...>);
3241 //
3242 // int main()
3243 // {
3244 // // user_function's `T` will be deduced to `int` and `Ints...`
3245 // // will be deduced to `0, 1, 2, 3, 4`.
3246 // user_function(make_integer_sequence<int, 5>());
3247 // }
3248 template <typename T, T... Ints>
3250 {
3251  using value_type = T;
3252  static constexpr std::size_t size() noexcept
3253  {
3254  return sizeof...(Ints);
3255  }
3256 };
3257 
3258 // index_sequence
3259 //
3260 // A helper template for an `integer_sequence` of `size_t`,
3261 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3262 // `std::index_sequence`.
3263 template <size_t... Ints>
3264 using index_sequence = integer_sequence<size_t, Ints...>;
3265 
3266 namespace utility_internal
3267 {
3268 
3269 template <typename Seq, size_t SeqSize, size_t Rem>
3270 struct Extend;
3271 
3272 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3273 template <typename T, T... Ints, size_t SeqSize>
3274 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3275 {
3276  using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3277 };
3278 
3279 template <typename T, T... Ints, size_t SeqSize>
3280 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3281 {
3282  using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3283 };
3284 
3285 // Recursion helper for 'make_integer_sequence<T, N>'.
3286 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3287 template <typename T, size_t N>
3288 struct Gen
3289 {
3290  using type =
3291  typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3292 };
3293 
3294 template <typename T>
3295 struct Gen<T, 0>
3296 {
3298 };
3299 
3300 } // namespace utility_internal
3301 
3302 // Compile-time sequences of integers
3303 
3304 // make_integer_sequence
3305 //
3306 // This template alias is equivalent to
3307 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3308 // replacement for C++14's `std::make_integer_sequence`.
3309 template <typename T, T N>
3311 
3312 // make_index_sequence
3313 //
3314 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3315 // and is designed to be a drop-in replacement for C++14's
3316 // `std::make_index_sequence`.
3317 template <size_t N>
3319 
3320 // index_sequence_for
3321 //
3322 // Converts a typename pack into an index sequence of the same length, and
3323 // is designed to be a drop-in replacement for C++14's
3324 // `std::index_sequence_for()`
3325 template <typename... Ts>
3327 
3329 
3330 #endif
3331 
3332 // dispatch utility (taken from ranges-v3)
3333 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3334 template<> struct priority_tag<0> {};
3335 
3336 // taken from ranges-v3
3337 template<typename T>
3339 {
3340  static JSON_INLINE_VARIABLE constexpr T value{};
3341 };
3342 
3343 #ifndef JSON_HAS_CPP_17
3344  template<typename T>
3345  constexpr T static_const<T>::value;
3346 #endif
3347 
3348 template<typename T, typename... Args>
3349 constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args)
3350 {
3351  return std::array<T, sizeof...(Args)> {{static_cast<T>(std::forward<Args>(args))...}};
3352 }
3353 
3354 } // namespace detail
3356 
3357 // #include <nlohmann/detail/meta/type_traits.hpp>
3358 // __ _____ _____ _____
3359 // __| | __| | | | JSON for Modern C++
3360 // | | |__ | | | | | | version 3.12.0
3361 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3362 //
3363 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3364 // SPDX-License-Identifier: MIT
3365 
3366 
3367 
3368 #include <limits> // numeric_limits
3369 #include <string> // char_traits
3370 #include <tuple> // tuple
3371 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3372 #include <utility> // declval
3373 
3374 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3375 // __ _____ _____ _____
3376 // __| | __| | | | JSON for Modern C++
3377 // | | |__ | | | | | | version 3.12.0
3378 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3379 //
3380 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3381 // SPDX-License-Identifier: MIT
3382 
3383 
3384 
3385 #include <iterator> // random_access_iterator_tag
3386 
3387 // #include <nlohmann/detail/abi_macros.hpp>
3388 
3389 // #include <nlohmann/detail/meta/void_t.hpp>
3390 
3391 // #include <nlohmann/detail/meta/cpp_future.hpp>
3392 
3393 
3395 namespace detail
3396 {
3397 
3398 template<typename It, typename = void>
3399 struct iterator_types {};
3400 
3401 template<typename It>
3403  It,
3404  void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3405  typename It::reference, typename It::iterator_category >>
3406 {
3407  using difference_type = typename It::difference_type;
3408  using value_type = typename It::value_type;
3409  using pointer = typename It::pointer;
3410  using reference = typename It::reference;
3411  using iterator_category = typename It::iterator_category;
3412 };
3413 
3414 // This is required as some compilers implement std::iterator_traits in a way that
3415 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3416 template<typename T, typename = void>
3418 {
3419 };
3420 
3421 template<typename T>
3422 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3423  : iterator_types<T>
3424 {
3425 };
3426 
3427 template<typename T>
3429 {
3430  using iterator_category = std::random_access_iterator_tag;
3431  using value_type = T;
3432  using difference_type = ptrdiff_t;
3433  using pointer = T*;
3434  using reference = T&;
3435 };
3436 
3437 } // namespace detail
3439 
3440 // #include <nlohmann/detail/macro_scope.hpp>
3441 
3442 // #include <nlohmann/detail/meta/call_std/begin.hpp>
3443 // __ _____ _____ _____
3444 // __| | __| | | | JSON for Modern C++
3445 // | | |__ | | | | | | version 3.12.0
3446 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3447 //
3448 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3449 // SPDX-License-Identifier: MIT
3450 
3451 
3452 
3453 // #include <nlohmann/detail/macro_scope.hpp>
3454 
3455 
3457 
3459 
3461 
3462 // #include <nlohmann/detail/meta/call_std/end.hpp>
3463 // __ _____ _____ _____
3464 // __| | __| | | | JSON for Modern C++
3465 // | | |__ | | | | | | version 3.12.0
3466 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3467 //
3468 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3469 // SPDX-License-Identifier: MIT
3470 
3471 
3472 
3473 // #include <nlohmann/detail/macro_scope.hpp>
3474 
3475 
3477 
3479 
3481 
3482 // #include <nlohmann/detail/meta/cpp_future.hpp>
3483 
3484 // #include <nlohmann/detail/meta/detected.hpp>
3485 
3486 // #include <nlohmann/json_fwd.hpp>
3487 // __ _____ _____ _____
3488 // __| | __| | | | JSON for Modern C++
3489 // | | |__ | | | | | | version 3.12.0
3490 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
3491 //
3492 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
3493 // SPDX-License-Identifier: MIT
3494 
3495 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3496  #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3497 
3498  #include <cstdint> // int64_t, uint64_t
3499  #include <map> // map
3500  #include <memory> // allocator
3501  #include <string> // string
3502  #include <vector> // vector
3503 
3504  // #include <nlohmann/detail/abi_macros.hpp>
3505 
3506 
3513 
3521  template<typename T = void, typename SFINAE = void>
3522  struct adl_serializer;
3523 
3526  template<template<typename U, typename V, typename... Args> class ObjectType =
3527  std::map,
3528  template<typename U, typename... Args> class ArrayType = std::vector,
3529  class StringType = std::string, class BooleanType = bool,
3530  class NumberIntegerType = std::int64_t,
3531  class NumberUnsignedType = std::uint64_t,
3532  class NumberFloatType = double,
3533  template<typename U> class AllocatorType = std::allocator,
3534  template<typename T, typename SFINAE = void> class JSONSerializer =
3536  class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
3537  class CustomBaseClass = void>
3538  class basic_json;
3539 
3542  template<typename RefStringType>
3543  class json_pointer;
3544 
3550 
3553  template<class Key, class T, class IgnoredLess, class Allocator>
3554  struct ordered_map;
3555 
3559 
3561 
3562 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3563 
3564 
3574 namespace detail
3575 {
3576 
3578 // helpers //
3580 
3581 // Note to maintainers:
3582 //
3583 // Every trait in this file expects a non CV-qualified type.
3584 // The only exceptions are in the 'aliases for detected' section
3585 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3586 //
3587 // In this case, T has to be properly CV-qualified to constraint the function arguments
3588 // (e.g. to_json(BasicJsonType&, const T&))
3589 
3590 template<typename> struct is_basic_json : std::false_type {};
3591 
3593 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3594 
3595 // used by exceptions create() member functions
3596 // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3597 // false_type otherwise
3598 template<typename BasicJsonContext>
3600  std::integral_constant < bool,
3601  is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3602  || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3603 {};
3604 
3606 // json_ref helpers //
3608 
3609 template<typename>
3610 class json_ref;
3611 
3612 template<typename>
3613 struct is_json_ref : std::false_type {};
3614 
3615 template<typename T>
3616 struct is_json_ref<json_ref<T>> : std::true_type {};
3617 
3619 // aliases for detected //
3621 
3622 template<typename T>
3623 using mapped_type_t = typename T::mapped_type;
3624 
3625 template<typename T>
3626 using key_type_t = typename T::key_type;
3627 
3628 template<typename T>
3629 using value_type_t = typename T::value_type;
3630 
3631 template<typename T>
3632 using difference_type_t = typename T::difference_type;
3633 
3634 template<typename T>
3635 using pointer_t = typename T::pointer;
3636 
3637 template<typename T>
3638 using reference_t = typename T::reference;
3639 
3640 template<typename T>
3641 using iterator_category_t = typename T::iterator_category;
3642 
3643 template<typename T, typename... Args>
3644 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3645 
3646 template<typename T, typename... Args>
3647 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3648 
3649 template<typename T, typename U>
3650 using get_template_function = decltype(std::declval<T>().template get<U>());
3651 
3652 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3653 template<typename BasicJsonType, typename T, typename = void>
3654 struct has_from_json : std::false_type {};
3655 
3656 // trait checking if j.get<T> is valid
3657 // use this trait instead of std::is_constructible or std::is_convertible,
3658 // both rely on, or make use of implicit conversions, and thus fail when T
3659 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3660 template <typename BasicJsonType, typename T>
3662 {
3664 };
3665 
3666 template<typename BasicJsonType, typename T>
3667 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3668 {
3669  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3670 
3671  static constexpr bool value =
3673  const BasicJsonType&, T&>::value;
3674 };
3675 
3676 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3677 // this overload is used for non-default-constructible user-defined-types
3678 template<typename BasicJsonType, typename T, typename = void>
3679 struct has_non_default_from_json : std::false_type {};
3680 
3681 template<typename BasicJsonType, typename T>
3682 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3683 {
3684  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3685 
3686  static constexpr bool value =
3688  const BasicJsonType&>::value;
3689 };
3690 
3691 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3692 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3693 template<typename BasicJsonType, typename T, typename = void>
3694 struct has_to_json : std::false_type {};
3695 
3696 template<typename BasicJsonType, typename T>
3697 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3698 {
3699  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3700 
3701  static constexpr bool value =
3702  is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3703  T>::value;
3704 };
3705 
3706 template<typename T>
3707 using detect_key_compare = typename T::key_compare;
3708 
3709 template<typename T>
3710 struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3711 
3712 // obtains the actual object key comparator
3713 template<typename BasicJsonType>
3715 {
3716  using object_t = typename BasicJsonType::object_t;
3717  using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3718  using type = typename std::conditional < has_key_compare<object_t>::value,
3719  typename object_t::key_compare, object_comparator_t>::type;
3720 };
3721 
3722 template<typename BasicJsonType>
3724 
3726 // char_traits //
3728 
3729 // Primary template of char_traits calls std char_traits
3730 template<typename T>
3731 struct char_traits : std::char_traits<T>
3732 {};
3733 
3734 // Explicitly define char traits for unsigned char since it is not standard
3735 template<>
3736 struct char_traits<unsigned char> : std::char_traits<char>
3737 {
3738  using char_type = unsigned char;
3739  using int_type = uint64_t;
3740 
3741  // Redefine to_int_type function
3742  static int_type to_int_type(char_type c) noexcept
3743  {
3744  return static_cast<int_type>(c);
3745  }
3746 
3747  static char_type to_char_type(int_type i) noexcept
3748  {
3749  return static_cast<char_type>(i);
3750  }
3751 
3752  static constexpr int_type eof() noexcept
3753  {
3754  return static_cast<int_type>(std::char_traits<char>::eof());
3755  }
3756 };
3757 
3758 // Explicitly define char traits for signed char since it is not standard
3759 template<>
3760 struct char_traits<signed char> : std::char_traits<char>
3761 {
3762  using char_type = signed char;
3763  using int_type = uint64_t;
3764 
3765  // Redefine to_int_type function
3766  static int_type to_int_type(char_type c) noexcept
3767  {
3768  return static_cast<int_type>(c);
3769  }
3770 
3771  static char_type to_char_type(int_type i) noexcept
3772  {
3773  return static_cast<char_type>(i);
3774  }
3775 
3776  static constexpr int_type eof() noexcept
3777  {
3778  return static_cast<int_type>(std::char_traits<char>::eof());
3779  }
3780 };
3781 
3783 // is_ functions //
3785 
3786 // https://en.cppreference.com/w/cpp/types/conjunction
3787 template<class...> struct conjunction : std::true_type { };
3788 template<class B> struct conjunction<B> : B { };
3789 template<class B, class... Bn>
3790 struct conjunction<B, Bn...>
3791 : std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
3792 
3793 // https://en.cppreference.com/w/cpp/types/negation
3794 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3795 
3796 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3797 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3798 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3799 template <typename T>
3800 struct is_default_constructible : std::is_default_constructible<T> {};
3801 
3802 template <typename T1, typename T2>
3803 struct is_default_constructible<std::pair<T1, T2>>
3804  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3805 
3806 template <typename T1, typename T2>
3807 struct is_default_constructible<const std::pair<T1, T2>>
3808  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3809 
3810 template <typename... Ts>
3811 struct is_default_constructible<std::tuple<Ts...>>
3812  : conjunction<is_default_constructible<Ts>...> {};
3813 
3814 template <typename... Ts>
3815 struct is_default_constructible<const std::tuple<Ts...>>
3816  : conjunction<is_default_constructible<Ts>...> {};
3817 
3818 template <typename T, typename... Args>
3819 struct is_constructible : std::is_constructible<T, Args...> {};
3820 
3821 template <typename T1, typename T2>
3822 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3823 
3824 template <typename T1, typename T2>
3825 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3826 
3827 template <typename... Ts>
3828 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3829 
3830 template <typename... Ts>
3831 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3832 
3833 template<typename T, typename = void>
3834 struct is_iterator_traits : std::false_type {};
3835 
3836 template<typename T>
3838 {
3839  private:
3840  using traits = iterator_traits<T>;
3841 
3842  public:
3843  static constexpr auto value =
3849 };
3850 
3851 template<typename T>
3852 struct is_range
3853 {
3854  private:
3855  using t_ref = typename std::add_lvalue_reference<T>::type;
3856 
3857  using iterator = detected_t<result_of_begin, t_ref>;
3858  using sentinel = detected_t<result_of_end, t_ref>;
3859 
3860  // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3861  // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3862  // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3863  static constexpr auto is_iterator_begin =
3865 
3866  public:
3867  static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3868 };
3869 
3870 template<typename R>
3871 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3872 
3873 template<typename T>
3875 
3876 // The following implementation of is_complete_type is taken from
3877 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3878 // and is written by Xiang Fan who agreed to using it in this library.
3879 
3880 template<typename T, typename = void>
3881 struct is_complete_type : std::false_type {};
3882 
3883 template<typename T>
3884 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3885 
3886 template<typename BasicJsonType, typename CompatibleObjectType,
3887  typename = void>
3888 struct is_compatible_object_type_impl : std::false_type {};
3889 
3890 template<typename BasicJsonType, typename CompatibleObjectType>
3892  BasicJsonType, CompatibleObjectType,
3893  enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3894  is_detected<key_type_t, CompatibleObjectType>::value >>
3895 {
3896  using object_t = typename BasicJsonType::object_t;
3897 
3898  // macOS's is_constructible does not play well with nonesuch...
3899  static constexpr bool value =
3900  is_constructible<typename object_t::key_type,
3901  typename CompatibleObjectType::key_type>::value &&
3902  is_constructible<typename object_t::mapped_type,
3903  typename CompatibleObjectType::mapped_type>::value;
3904 };
3905 
3906 template<typename BasicJsonType, typename CompatibleObjectType>
3908  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3909 
3910 template<typename BasicJsonType, typename ConstructibleObjectType,
3911  typename = void>
3912 struct is_constructible_object_type_impl : std::false_type {};
3913 
3914 template<typename BasicJsonType, typename ConstructibleObjectType>
3916  BasicJsonType, ConstructibleObjectType,
3917  enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3918  is_detected<key_type_t, ConstructibleObjectType>::value >>
3919 {
3920  using object_t = typename BasicJsonType::object_t;
3921 
3922  static constexpr bool value =
3924  (std::is_move_assignable<ConstructibleObjectType>::value ||
3925  std::is_copy_assignable<ConstructibleObjectType>::value) &&
3926  (is_constructible<typename ConstructibleObjectType::key_type,
3927  typename object_t::key_type>::value &&
3928  std::is_same <
3929  typename object_t::mapped_type,
3930  typename ConstructibleObjectType::mapped_type >::value)) ||
3931  (has_from_json<BasicJsonType,
3932  typename ConstructibleObjectType::mapped_type>::value ||
3934  BasicJsonType,
3935  typename ConstructibleObjectType::mapped_type >::value);
3936 };
3937 
3938 template<typename BasicJsonType, typename ConstructibleObjectType>
3940  : is_constructible_object_type_impl<BasicJsonType,
3941  ConstructibleObjectType> {};
3942 
3943 template<typename BasicJsonType, typename CompatibleStringType>
3945 {
3946  static constexpr auto value =
3948 };
3949 
3950 template<typename BasicJsonType, typename ConstructibleStringType>
3952 {
3953  // launder type through decltype() to fix compilation failure on ICPC
3954 #ifdef __INTEL_COMPILER
3955  using laundered_type = decltype(std::declval<ConstructibleStringType>());
3956 #else
3957  using laundered_type = ConstructibleStringType;
3958 #endif
3959 
3960  static constexpr auto value =
3961  conjunction <
3963  is_detected_exact<typename BasicJsonType::string_t::value_type,
3965 };
3966 
3967 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3968 struct is_compatible_array_type_impl : std::false_type {};
3969 
3970 template<typename BasicJsonType, typename CompatibleArrayType>
3972  BasicJsonType, CompatibleArrayType,
3973  enable_if_t <
3974  is_detected<iterator_t, CompatibleArrayType>::value&&
3975  is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3976 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3977 // c.f. https://github.com/nlohmann/json/pull/3073
3978  !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3979 {
3980  static constexpr bool value =
3981  is_constructible<BasicJsonType,
3983 };
3984 
3985 template<typename BasicJsonType, typename CompatibleArrayType>
3987  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3988 
3989 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3990 struct is_constructible_array_type_impl : std::false_type {};
3991 
3992 template<typename BasicJsonType, typename ConstructibleArrayType>
3994  BasicJsonType, ConstructibleArrayType,
3995  enable_if_t<std::is_same<ConstructibleArrayType,
3996  typename BasicJsonType::value_type>::value >>
3997  : std::true_type {};
3998 
3999 template<typename BasicJsonType, typename ConstructibleArrayType>
4001  BasicJsonType, ConstructibleArrayType,
4002  enable_if_t < !std::is_same<ConstructibleArrayType,
4003  typename BasicJsonType::value_type>::value&&
4004  !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
4005  is_default_constructible<ConstructibleArrayType>::value&&
4006 (std::is_move_assignable<ConstructibleArrayType>::value ||
4007  std::is_copy_assignable<ConstructibleArrayType>::value)&&
4008 is_detected<iterator_t, ConstructibleArrayType>::value&&
4009 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
4010 is_detected<range_value_t, ConstructibleArrayType>::value&&
4011 // special case for types like std::filesystem::path whose iterator's value_type are themselves
4012 // c.f. https://github.com/nlohmann/json/pull/3073
4013 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
4015 detected_t<range_value_t, ConstructibleArrayType >>::value >>
4016 {
4018 
4019  static constexpr bool value =
4020  std::is_same<value_type,
4021  typename BasicJsonType::array_t::value_type>::value ||
4022  has_from_json<BasicJsonType,
4023  value_type>::value ||
4025  BasicJsonType,
4026  value_type >::value;
4027 };
4028 
4029 template<typename BasicJsonType, typename ConstructibleArrayType>
4031  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
4032 
4033 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
4034  typename = void>
4035 struct is_compatible_integer_type_impl : std::false_type {};
4036 
4037 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
4039  RealIntegerType, CompatibleNumberIntegerType,
4040  enable_if_t < std::is_integral<RealIntegerType>::value&&
4041  std::is_integral<CompatibleNumberIntegerType>::value&&
4042  !std::is_same<bool, CompatibleNumberIntegerType>::value >>
4043 {
4044  // is there an assert somewhere on overflows?
4045  using RealLimits = std::numeric_limits<RealIntegerType>;
4046  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
4047 
4048  static constexpr auto value =
4049  is_constructible<RealIntegerType,
4050  CompatibleNumberIntegerType>::value &&
4051  CompatibleLimits::is_integer &&
4052  RealLimits::is_signed == CompatibleLimits::is_signed;
4053 };
4054 
4055 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
4057  : is_compatible_integer_type_impl<RealIntegerType,
4058  CompatibleNumberIntegerType> {};
4059 
4060 template<typename BasicJsonType, typename CompatibleType, typename = void>
4061 struct is_compatible_type_impl: std::false_type {};
4062 
4063 template<typename BasicJsonType, typename CompatibleType>
4065  BasicJsonType, CompatibleType,
4066  enable_if_t<is_complete_type<CompatibleType>::value >>
4067 {
4068  static constexpr bool value =
4070 };
4071 
4072 template<typename BasicJsonType, typename CompatibleType>
4074  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
4075 
4076 template<typename T1, typename T2>
4077 struct is_constructible_tuple : std::false_type {};
4078 
4079 template<typename T1, typename... Args>
4080 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
4081 
4082 template<typename BasicJsonType, typename T>
4083 struct is_json_iterator_of : std::false_type {};
4084 
4085 template<typename BasicJsonType>
4086 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
4087 
4088 template<typename BasicJsonType>
4089 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
4090 {};
4091 
4092 // checks if a given type T is a template specialization of Primary
4093 template<template <typename...> class Primary, typename T>
4094 struct is_specialization_of : std::false_type {};
4095 
4096 template<template <typename...> class Primary, typename... Args>
4097 struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
4098 
4099 template<typename T>
4101 
4102 // checks if A and B are comparable using Compare functor
4103 template<typename Compare, typename A, typename B, typename = void>
4104 struct is_comparable : std::false_type {};
4105 
4106 template<typename Compare, typename A, typename B>
4107 struct is_comparable<Compare, A, B, void_t<
4108 decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
4109 decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
4110 >> : std::true_type {};
4111 
4112 template<typename T>
4114 
4115 // type trait to check if KeyType can be used as object key (without a BasicJsonType)
4116 // see is_usable_as_basic_json_key_type below
4117 template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
4118  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
4119 using is_usable_as_key_type = typename std::conditional <
4121  && !(ExcludeObjectKeyType && std::is_same<KeyType,
4122  ObjectKeyType>::value)
4123  && (!RequireTransparentComparator
4126  std::true_type,
4127  std::false_type >::type;
4128 
4129 // type trait to check if KeyType can be used as object key
4130 // true if:
4131 // - KeyType is comparable with BasicJsonType::object_t::key_type
4132 // - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
4133 // - the comparator is transparent or RequireTransparentComparator is false
4134 // - KeyType is not a JSON iterator or json_pointer
4135 template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
4136  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
4137 using is_usable_as_basic_json_key_type = typename std::conditional <
4138  is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
4139  typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
4140  RequireTransparentComparator, ExcludeObjectKeyType>::value
4142  std::true_type,
4143  std::false_type >::type;
4144 
4145 template<typename ObjectType, typename KeyType>
4146 using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
4147 
4148 // type trait to check if object_t has an erase() member functions accepting KeyType
4149 template<typename BasicJsonType, typename KeyType>
4150 using has_erase_with_key_type = typename std::conditional <
4151  is_detected <
4153  typename BasicJsonType::object_t, KeyType >::value,
4154  std::true_type,
4155  std::false_type >::type;
4156 
4157 // a naive helper to check if a type is an ordered_map (exploits the fact that
4158 // ordered_map inherits capacity() from std::vector)
4159 template <typename T>
4161 {
4162  using one = char;
4163 
4164  struct two
4165  {
4166  char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4167  };
4168 
4169  template <typename C> static one test( decltype(&C::capacity) ) ;
4170  template <typename C> static two test(...);
4171 
4172  enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
4173 };
4174 
4175 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
4176 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
4178 {
4179  return static_cast<T>(value);
4180 }
4181 
4182 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
4183 T conditional_static_cast(U value)
4184 {
4185  return value;
4186 }
4187 
4188 template<typename... Types>
4190 
4191 template<typename... Types>
4193 
4194 template<typename... Types>
4196 
4197 // there's a disjunction trait in another PR; replace when merged
4198 template<typename... Types>
4199 using same_sign = std::integral_constant < bool,
4200  all_signed<Types...>::value || all_unsigned<Types...>::value >;
4201 
4202 template<typename OfType, typename T>
4203 using never_out_of_range = std::integral_constant < bool,
4204  (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
4205  || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
4206 
4207 template<typename OfType, typename T,
4208  bool OfTypeSigned = std::is_signed<OfType>::value,
4209  bool TSigned = std::is_signed<T>::value>
4211 
4212 template<typename OfType, typename T>
4213 struct value_in_range_of_impl2<OfType, T, false, false>
4214 {
4215  static constexpr bool test(T val)
4216  {
4217  using CommonType = typename std::common_type<OfType, T>::type;
4218  return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4219  }
4220 };
4221 
4222 template<typename OfType, typename T>
4223 struct value_in_range_of_impl2<OfType, T, true, false>
4224 {
4225  static constexpr bool test(T val)
4226  {
4227  using CommonType = typename std::common_type<OfType, T>::type;
4228  return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4229  }
4230 };
4231 
4232 template<typename OfType, typename T>
4233 struct value_in_range_of_impl2<OfType, T, false, true>
4234 {
4235  static constexpr bool test(T val)
4236  {
4237  using CommonType = typename std::common_type<OfType, T>::type;
4238  return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4239  }
4240 };
4241 
4242 template<typename OfType, typename T>
4243 struct value_in_range_of_impl2<OfType, T, true, true>
4244 {
4245  static constexpr bool test(T val)
4246  {
4247  using CommonType = typename std::common_type<OfType, T>::type;
4248  return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
4249  && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4250  }
4251 };
4252 
4253 template<typename OfType, typename T,
4254  bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
4257 
4258 template<typename OfType, typename T>
4259 struct value_in_range_of_impl1<OfType, T, false>
4260 {
4261  static constexpr bool test(T val)
4262  {
4264  }
4265 };
4266 
4267 template<typename OfType, typename T>
4268 struct value_in_range_of_impl1<OfType, T, true>
4269 {
4270  static constexpr bool test(T /*val*/)
4271  {
4272  return true;
4273  }
4274 };
4275 
4276 template<typename OfType, typename T>
4277 constexpr bool value_in_range_of(T val)
4278 {
4280 }
4281 
4282 template<bool Value>
4283 using bool_constant = std::integral_constant<bool, Value>;
4284 
4286 // is_c_string
4288 
4289 namespace impl
4290 {
4291 
4292 template<typename T>
4293 constexpr bool is_c_string()
4294 {
4295  using TUnExt = typename std::remove_extent<T>::type;
4296  using TUnCVExt = typename std::remove_cv<TUnExt>::type;
4297  using TUnPtr = typename std::remove_pointer<T>::type;
4298  using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
4299  return
4300  (std::is_array<T>::value && std::is_same<TUnCVExt, char>::value)
4301  || (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);
4302 }
4303 
4304 } // namespace impl
4305 
4306 // checks whether T is a [cv] char */[cv] char[] C string
4307 template<typename T>
4308 struct is_c_string : bool_constant<impl::is_c_string<T>()> {};
4309 
4310 template<typename T>
4312 
4314 // is_transparent
4316 
4317 namespace impl
4318 {
4319 
4320 template<typename T>
4321 constexpr bool is_transparent()
4322 {
4324 }
4325 
4326 } // namespace impl
4327 
4328 // checks whether T has a member named is_transparent
4329 template<typename T>
4330 struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
4331 
4333 
4334 } // namespace detail
4336 
4337 // #include <nlohmann/detail/string_concat.hpp>
4338 // __ _____ _____ _____
4339 // __| | __| | | | JSON for Modern C++
4340 // | | |__ | | | | | | version 3.12.0
4341 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4342 //
4343 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
4344 // SPDX-License-Identifier: MIT
4345 
4346 
4347 
4348 #include <cstring> // strlen
4349 #include <string> // string
4350 #include <utility> // forward
4351 
4352 // #include <nlohmann/detail/meta/cpp_future.hpp>
4353 
4354 // #include <nlohmann/detail/meta/detected.hpp>
4355 
4356 
4358 namespace detail
4359 {
4360 
4361 inline std::size_t concat_length()
4362 {
4363  return 0;
4364 }
4365 
4366 template<typename... Args>
4367 inline std::size_t concat_length(const char* cstr, const Args& ... rest);
4368 
4369 template<typename StringType, typename... Args>
4370 inline std::size_t concat_length(const StringType& str, const Args& ... rest);
4371 
4372 template<typename... Args>
4373 inline std::size_t concat_length(const char /*c*/, const Args& ... rest)
4374 {
4375  return 1 + concat_length(rest...);
4376 }
4377 
4378 template<typename... Args>
4379 inline std::size_t concat_length(const char* cstr, const Args& ... rest)
4380 {
4381  // cppcheck-suppress ignoredReturnValue
4382  return ::strlen(cstr) + concat_length(rest...);
4383 }
4384 
4385 template<typename StringType, typename... Args>
4386 inline std::size_t concat_length(const StringType& str, const Args& ... rest)
4387 {
4388  return str.size() + concat_length(rest...);
4389 }
4390 
4391 template<typename OutStringType>
4392 inline void concat_into(OutStringType& /*out*/)
4393 {}
4394 
4395 template<typename StringType, typename Arg>
4396 using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
4397 
4398 template<typename StringType, typename Arg>
4400 
4401 template<typename StringType, typename Arg>
4402 using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
4403 
4404 template<typename StringType, typename Arg>
4406 
4407 template<typename StringType, typename Arg>
4408 using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
4409 
4410 template<typename StringType, typename Arg>
4412 
4413 template<typename StringType, typename Arg>
4414 using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
4415 
4416 template<typename StringType, typename Arg>
4418 
4419 template < typename OutStringType, typename Arg, typename... Args,
4422 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
4423 
4424 template < typename OutStringType, typename Arg, typename... Args,
4428 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4429 
4430 template < typename OutStringType, typename Arg, typename... Args,
4435 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4436 
4437 template<typename OutStringType, typename Arg, typename... Args,
4439 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)
4440 {
4441  out.append(std::forward<Arg>(arg));
4442  concat_into(out, std::forward<Args>(rest)...);
4443 }
4444 
4445 template < typename OutStringType, typename Arg, typename... Args,
4446  enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4447  && detect_string_can_append_op<OutStringType, Arg>::value, int > >
4448 inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
4449 {
4450  out += std::forward<Arg>(arg);
4451  concat_into(out, std::forward<Args>(rest)...);
4452 }
4453 
4454 template < typename OutStringType, typename Arg, typename... Args,
4455  enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4456  && !detect_string_can_append_op<OutStringType, Arg>::value
4457  && detect_string_can_append_iter<OutStringType, Arg>::value, int > >
4458 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4459 {
4460  out.append(arg.begin(), arg.end());
4461  concat_into(out, std::forward<Args>(rest)...);
4462 }
4463 
4464 template < typename OutStringType, typename Arg, typename... Args,
4465  enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4466  && !detect_string_can_append_op<OutStringType, Arg>::value
4467  && !detect_string_can_append_iter<OutStringType, Arg>::value
4468  && detect_string_can_append_data<OutStringType, Arg>::value, int > >
4469 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4470 {
4471  out.append(arg.data(), arg.size());
4472  concat_into(out, std::forward<Args>(rest)...);
4473 }
4474 
4475 template<typename OutStringType = std::string, typename... Args>
4476 inline OutStringType concat(Args && ... args)
4477 {
4478  OutStringType str;
4479  str.reserve(concat_length(args...));
4480  concat_into(str, std::forward<Args>(args)...);
4481  return str;
4482 }
4483 
4484 } // namespace detail
4486 
4487 
4488 // With -Wweak-vtables, Clang will complain about the exception classes as they
4489 // have no out-of-line virtual method definitions and their vtable will be
4490 // emitted in every translation unit. This issue cannot be fixed with a
4491 // header-only library as there is no implementation file to move these
4492 // functions to. As a result, we suppress this warning here to avoid client
4493 // code to stumble over this. See https://github.com/nlohmann/json/issues/4087
4494 // for a discussion.
4495 #if defined(__clang__)
4496  #pragma clang diagnostic push
4497  #pragma clang diagnostic ignored "-Wweak-vtables"
4498 #endif
4499 
4501 namespace detail
4502 {
4503 
4505 // exceptions //
4507 
4510 class exception : public std::exception
4511 {
4512  public:
4514  const char* what() const noexcept override
4515  {
4516  return m.what();
4517  }
4518 
4520  const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
4521 
4522  protected:
4524  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
4525 
4526  static std::string name(const std::string& ename, int id_)
4527  {
4528  return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
4529  }
4530 
4531  static std::string diagnostics(std::nullptr_t /*leaf_element*/)
4532  {
4533  return "";
4534  }
4535 
4536  template<typename BasicJsonType>
4537  static std::string diagnostics(const BasicJsonType* leaf_element)
4538  {
4539 #if JSON_DIAGNOSTICS
4540  std::vector<std::string> tokens;
4541  for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
4542  {
4543  switch (current->m_parent->type())
4544  {
4545  case value_t::array:
4546  {
4547  for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i)
4548  {
4549  if (&current->m_parent->m_data.m_value.array->operator[](i) == current)
4550  {
4551  tokens.emplace_back(std::to_string(i));
4552  break;
4553  }
4554  }
4555  break;
4556  }
4557 
4558  case value_t::object:
4559  {
4560  for (const auto& element : *current->m_parent->m_data.m_value.object)
4561  {
4562  if (&element.second == current)
4563  {
4564  tokens.emplace_back(element.first.c_str());
4565  break;
4566  }
4567  }
4568  break;
4569  }
4570 
4571  case value_t::null: // LCOV_EXCL_LINE
4572  case value_t::string: // LCOV_EXCL_LINE
4573  case value_t::boolean: // LCOV_EXCL_LINE
4574  case value_t::number_integer: // LCOV_EXCL_LINE
4575  case value_t::number_unsigned: // LCOV_EXCL_LINE
4576  case value_t::number_float: // LCOV_EXCL_LINE
4577  case value_t::binary: // LCOV_EXCL_LINE
4578  case value_t::discarded: // LCOV_EXCL_LINE
4579  default: // LCOV_EXCL_LINE
4580  break; // LCOV_EXCL_LINE
4581  }
4582  }
4583 
4584  if (tokens.empty())
4585  {
4586  return "";
4587  }
4588 
4589  auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
4590  [](const std::string & a, const std::string & b)
4591  {
4592  return concat(a, '/', detail::escape(b));
4593  });
4594 
4595  return concat('(', str, ") ", get_byte_positions(leaf_element));
4596 #else
4597  return get_byte_positions(leaf_element);
4598 #endif
4599  }
4600 
4601  private:
4603  std::runtime_error m;
4604 #if JSON_DIAGNOSTIC_POSITIONS
4605  template<typename BasicJsonType>
4606  static std::string get_byte_positions(const BasicJsonType* leaf_element)
4607  {
4608  if ((leaf_element->start_pos() != std::string::npos) && (leaf_element->end_pos() != std::string::npos))
4609  {
4610  return concat("(bytes ", std::to_string(leaf_element->start_pos()), "-", std::to_string(leaf_element->end_pos()), ") ");
4611  }
4612  return "";
4613  }
4614 #else
4615  template<typename BasicJsonType>
4616  static std::string get_byte_positions(const BasicJsonType* leaf_element)
4617  {
4618  static_cast<void>(leaf_element);
4619  return "";
4620  }
4621 #endif
4622 };
4623 
4626 class parse_error : public exception
4627 {
4628  public:
4638  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4639  static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
4640  {
4641  const std::string w = concat(exception::name("parse_error", id_), "parse error",
4642  position_string(pos), ": ", exception::diagnostics(context), what_arg);
4643  return {id_, pos.chars_read_total, w.c_str()};
4644  }
4645 
4646  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4647  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
4648  {
4649  const std::string w = concat(exception::name("parse_error", id_), "parse error",
4650  (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
4651  ": ", exception::diagnostics(context), what_arg);
4652  return {id_, byte_, w.c_str()};
4653  }
4654 
4664  const std::size_t byte;
4665 
4666  private:
4667  parse_error(int id_, std::size_t byte_, const char* what_arg)
4668  : exception(id_, what_arg), byte(byte_) {}
4669 
4670  static std::string position_string(const position_t& pos)
4671  {
4672  return concat(" at line ", std::to_string(pos.lines_read + 1),
4673  ", column ", std::to_string(pos.chars_read_current_line));
4674  }
4675 };
4676 
4680 {
4681  public:
4682  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4683  static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4684  {
4685  const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4686  return {id_, w.c_str()};
4687  }
4688 
4689  private:
4691  invalid_iterator(int id_, const char* what_arg)
4692  : exception(id_, what_arg) {}
4693 };
4694 
4697 class type_error : public exception
4698 {
4699  public:
4700  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4701  static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4702  {
4703  const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4704  return {id_, w.c_str()};
4705  }
4706 
4707  private:
4709  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4710 };
4711 
4714 class out_of_range : public exception
4715 {
4716  public:
4717  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4718  static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4719  {
4720  const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4721  return {id_, w.c_str()};
4722  }
4723 
4724  private:
4726  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4727 };
4728 
4731 class other_error : public exception
4732 {
4733  public:
4734  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4735  static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4736  {
4737  const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4738  return {id_, w.c_str()};
4739  }
4740 
4741  private:
4743  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4744 };
4745 
4746 } // namespace detail
4748 
4749 #if defined(__clang__)
4750  #pragma clang diagnostic pop
4751 #endif
4752 
4753 // #include <nlohmann/detail/macro_scope.hpp>
4754 
4755 // #include <nlohmann/detail/meta/cpp_future.hpp>
4756 
4757 // #include <nlohmann/detail/meta/identity_tag.hpp>
4758 // __ _____ _____ _____
4759 // __| | __| | | | JSON for Modern C++
4760 // | | |__ | | | | | | version 3.12.0
4761 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4762 //
4763 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
4764 // SPDX-License-Identifier: MIT
4765 
4766 
4767 
4768 // #include <nlohmann/detail/abi_macros.hpp>
4769 
4770 
4772 namespace detail
4773 {
4774 
4775 // dispatching helper struct
4776 template <class T> struct identity_tag {};
4777 
4778 } // namespace detail
4780 
4781 // #include <nlohmann/detail/meta/std_fs.hpp>
4782 // __ _____ _____ _____
4783 // __| | __| | | | JSON for Modern C++
4784 // | | |__ | | | | | | version 3.12.0
4785 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
4786 //
4787 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
4788 // SPDX-License-Identifier: MIT
4789 
4790 
4791 
4792 // #include <nlohmann/detail/macro_scope.hpp>
4793 
4794 
4795 #if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4796 #include <experimental/filesystem>
4798 namespace detail
4799 {
4800 namespace std_fs = std::experimental::filesystem;
4801 } // namespace detail
4803 #elif JSON_HAS_FILESYSTEM
4804 #include <filesystem> // NOLINT(build/c++17)
4806 namespace detail
4807 {
4808 namespace std_fs = std::filesystem;
4809 } // namespace detail
4811 #endif
4812 
4813 // #include <nlohmann/detail/meta/type_traits.hpp>
4814 
4815 // #include <nlohmann/detail/string_concat.hpp>
4816 
4817 // #include <nlohmann/detail/value_t.hpp>
4818 
4819 
4821 namespace detail
4822 {
4823 
4824 template<typename BasicJsonType>
4825 inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4826 {
4827  if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4828  {
4829  JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4830  }
4831  n = nullptr;
4832 }
4833 
4834 #ifdef JSON_HAS_CPP_17
4835 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
4836 template<typename BasicJsonType, typename T>
4837 void from_json(const BasicJsonType& j, std::optional<T>& opt)
4838 {
4839  if (j.is_null())
4840  {
4841  opt = std::nullopt;
4842  }
4843  else
4844  {
4845  opt.emplace(j.template get<T>());
4846  }
4847 }
4848 
4849 #endif // JSON_USE_IMPLICIT_CONVERSIONS
4850 #endif // JSON_HAS_CPP_17
4851 
4852 // overloads for basic_json template parameters
4853 template < typename BasicJsonType, typename ArithmeticType,
4854  enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
4855  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4856  int > = 0 >
4857 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4858 {
4859  switch (static_cast<value_t>(j))
4860  {
4862  {
4863  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4864  break;
4865  }
4867  {
4868  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4869  break;
4870  }
4871  case value_t::number_float:
4872  {
4873  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4874  break;
4875  }
4876 
4877  case value_t::null:
4878  case value_t::object:
4879  case value_t::array:
4880  case value_t::string:
4881  case value_t::boolean:
4882  case value_t::binary:
4883  case value_t::discarded:
4884  default:
4885  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4886  }
4887 }
4888 
4889 template<typename BasicJsonType>
4890 inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4891 {
4892  if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4893  {
4894  JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4895  }
4896  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4897 }
4898 
4899 template<typename BasicJsonType>
4900 inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4901 {
4902  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4903  {
4904  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4905  }
4906  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4907 }
4908 
4909 template <
4910  typename BasicJsonType, typename StringType,
4911  enable_if_t <
4912  std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
4913  && is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value
4914  && !std::is_same<typename BasicJsonType::string_t, StringType>::value
4915  && !is_json_ref<StringType>::value, int > = 0 >
4916 inline void from_json(const BasicJsonType& j, StringType& s)
4917 {
4918  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4919  {
4920  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4921  }
4922 
4923  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4924 }
4925 
4926 template<typename BasicJsonType>
4927 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4928 {
4929  get_arithmetic_value(j, val);
4930 }
4931 
4932 template<typename BasicJsonType>
4933 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4934 {
4935  get_arithmetic_value(j, val);
4936 }
4937 
4938 template<typename BasicJsonType>
4939 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4940 {
4941  get_arithmetic_value(j, val);
4942 }
4943 
4944 #if !JSON_DISABLE_ENUM_SERIALIZATION
4945 template<typename BasicJsonType, typename EnumType,
4946  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4947 inline void from_json(const BasicJsonType& j, EnumType& e)
4948 {
4949  typename std::underlying_type<EnumType>::type val;
4950  get_arithmetic_value(j, val);
4951  e = static_cast<EnumType>(val);
4952 }
4953 #endif // JSON_DISABLE_ENUM_SERIALIZATION
4954 
4955 // forward_list doesn't have an insert method
4956 template<typename BasicJsonType, typename T, typename Allocator,
4957  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4958 inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4959 {
4960  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4961  {
4962  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4963  }
4964  l.clear();
4965  std::transform(j.rbegin(), j.rend(),
4966  std::front_inserter(l), [](const BasicJsonType & i)
4967  {
4968  return i.template get<T>();
4969  });
4970 }
4971 
4972 // valarray doesn't have an insert method
4973 template<typename BasicJsonType, typename T,
4974  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4975 inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
4976 {
4977  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4978  {
4979  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4980  }
4981  l.resize(j.size());
4982  std::transform(j.begin(), j.end(), std::begin(l),
4983  [](const BasicJsonType & elem)
4984  {
4985  return elem.template get<T>();
4986  });
4987 }
4988 
4989 template<typename BasicJsonType, typename T, std::size_t N>
4990 auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4991 -> decltype(j.template get<T>(), void())
4992 {
4993  for (std::size_t i = 0; i < N; ++i)
4994  {
4995  arr[i] = j.at(i).template get<T>();
4996  }
4997 }
4998 
4999 template<typename BasicJsonType, typename T, std::size_t N1, std::size_t N2>
5000 auto from_json(const BasicJsonType& j, T (&arr)[N1][N2]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5001 -> decltype(j.template get<T>(), void())
5002 {
5003  for (std::size_t i1 = 0; i1 < N1; ++i1)
5004  {
5005  for (std::size_t i2 = 0; i2 < N2; ++i2)
5006  {
5007  arr[i1][i2] = j.at(i1).at(i2).template get<T>();
5008  }
5009  }
5010 }
5011 
5012 template<typename BasicJsonType, typename T, std::size_t N1, std::size_t N2, std::size_t N3>
5013 auto from_json(const BasicJsonType& j, T (&arr)[N1][N2][N3]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5014 -> decltype(j.template get<T>(), void())
5015 {
5016  for (std::size_t i1 = 0; i1 < N1; ++i1)
5017  {
5018  for (std::size_t i2 = 0; i2 < N2; ++i2)
5019  {
5020  for (std::size_t i3 = 0; i3 < N3; ++i3)
5021  {
5022  arr[i1][i2][i3] = j.at(i1).at(i2).at(i3).template get<T>();
5023  }
5024  }
5025  }
5026 }
5027 
5028 template<typename BasicJsonType, typename T, std::size_t N1, std::size_t N2, std::size_t N3, std::size_t N4>
5029 auto from_json(const BasicJsonType& j, T (&arr)[N1][N2][N3][N4]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5030 -> decltype(j.template get<T>(), void())
5031 {
5032  for (std::size_t i1 = 0; i1 < N1; ++i1)
5033  {
5034  for (std::size_t i2 = 0; i2 < N2; ++i2)
5035  {
5036  for (std::size_t i3 = 0; i3 < N3; ++i3)
5037  {
5038  for (std::size_t i4 = 0; i4 < N4; ++i4)
5039  {
5040  arr[i1][i2][i3][i4] = j.at(i1).at(i2).at(i3).at(i4).template get<T>();
5041  }
5042  }
5043  }
5044  }
5045 }
5046 
5047 template<typename BasicJsonType>
5048 inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
5049 {
5050  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
5051 }
5052 
5053 template<typename BasicJsonType, typename T, std::size_t N>
5054 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
5055  priority_tag<2> /*unused*/)
5056 -> decltype(j.template get<T>(), void())
5057 {
5058  for (std::size_t i = 0; i < N; ++i)
5059  {
5060  arr[i] = j.at(i).template get<T>();
5061  }
5062 }
5063 
5064 template<typename BasicJsonType, typename ConstructibleArrayType,
5065  enable_if_t<
5066  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
5067  int> = 0>
5068 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
5069 -> decltype(
5070  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
5071  j.template get<typename ConstructibleArrayType::value_type>(),
5072  void())
5073 {
5074  using std::end;
5075 
5076  ConstructibleArrayType ret;
5077  ret.reserve(j.size());
5078  std::transform(j.begin(), j.end(),
5079  std::inserter(ret, end(ret)), [](const BasicJsonType & i)
5080  {
5081  // get<BasicJsonType>() returns *this, this won't call a from_json
5082  // method when value_type is BasicJsonType
5083  return i.template get<typename ConstructibleArrayType::value_type>();
5084  });
5085  arr = std::move(ret);
5086 }
5087 
5088 template<typename BasicJsonType, typename ConstructibleArrayType,
5089  enable_if_t<
5090  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
5091  int> = 0>
5092 inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
5093  priority_tag<0> /*unused*/)
5094 {
5095  using std::end;
5096 
5097  ConstructibleArrayType ret;
5098  std::transform(
5099  j.begin(), j.end(), std::inserter(ret, end(ret)),
5100  [](const BasicJsonType & i)
5101  {
5102  // get<BasicJsonType>() returns *this, this won't call a from_json
5103  // method when value_type is BasicJsonType
5104  return i.template get<typename ConstructibleArrayType::value_type>();
5105  });
5106  arr = std::move(ret);
5107 }
5108 
5109 template < typename BasicJsonType, typename ConstructibleArrayType,
5110  enable_if_t <
5111  is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
5112  !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
5114  !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
5115  !is_basic_json<ConstructibleArrayType>::value,
5116  int > = 0 >
5117 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
5118 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
5119 j.template get<typename ConstructibleArrayType::value_type>(),
5120 void())
5121 {
5122  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5123  {
5124  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5125  }
5126 
5127  from_json_array_impl(j, arr, priority_tag<3> {});
5128 }
5129 
5130 template < typename BasicJsonType, typename T, std::size_t... Idx >
5131 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
5132  identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
5133 {
5134  return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
5135 }
5136 
5137 template < typename BasicJsonType, typename T, std::size_t N >
5138 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
5139 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
5140 {
5141  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5142  {
5143  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5144  }
5145 
5146  return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
5147 }
5148 
5149 template<typename BasicJsonType>
5150 inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
5151 {
5152  if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
5153  {
5154  JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
5155  }
5156 
5157  bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
5158 }
5159 
5160 template<typename BasicJsonType, typename ConstructibleObjectType,
5161  enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
5162 inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
5163 {
5164  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
5165  {
5166  JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
5167  }
5168 
5169  ConstructibleObjectType ret;
5170  const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
5171  using value_type = typename ConstructibleObjectType::value_type;
5172  std::transform(
5173  inner_object->begin(), inner_object->end(),
5174  std::inserter(ret, ret.begin()),
5175  [](typename BasicJsonType::object_t::value_type const & p)
5176  {
5177  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
5178  });
5179  obj = std::move(ret);
5180 }
5181 
5182 // overload for arithmetic types, not chosen for basic_json template arguments
5183 // (BooleanType, etc..); note: Is it really necessary to provide explicit
5184 // overloads for boolean_t etc. in case of a custom BooleanType which is not
5185 // an arithmetic type?
5186 template < typename BasicJsonType, typename ArithmeticType,
5187  enable_if_t <
5188  std::is_arithmetic<ArithmeticType>::value&&
5189  !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
5190  !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
5191  !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
5192  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
5193  int > = 0 >
5194 inline void from_json(const BasicJsonType& j, ArithmeticType& val)
5195 {
5196  switch (static_cast<value_t>(j))
5197  {
5199  {
5200  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
5201  break;
5202  }
5204  {
5205  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
5206  break;
5207  }
5208  case value_t::number_float:
5209  {
5210  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
5211  break;
5212  }
5213  case value_t::boolean:
5214  {
5215  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
5216  break;
5217  }
5218 
5219  case value_t::null:
5220  case value_t::object:
5221  case value_t::array:
5222  case value_t::string:
5223  case value_t::binary:
5224  case value_t::discarded:
5225  default:
5226  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
5227  }
5228 }
5229 
5230 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
5231 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
5232 {
5233  return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
5234 }
5235 
5236 template<typename BasicJsonType>
5237 std::tuple<> from_json_tuple_impl_base(BasicJsonType& /*unused*/, index_sequence<> /*unused*/)
5238 {
5239  return {};
5240 }
5241 
5242 template < typename BasicJsonType, class A1, class A2 >
5243 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
5244 {
5245  return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
5246  std::forward<BasicJsonType>(j).at(1).template get<A2>()};
5247 }
5248 
5249 template<typename BasicJsonType, typename A1, typename A2>
5250 inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
5251 {
5252  p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
5253 }
5254 
5255 template<typename BasicJsonType, typename... Args>
5256 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
5257 {
5258  return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
5259 }
5260 
5261 template<typename BasicJsonType, typename... Args>
5262 inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
5263 {
5264  t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
5265 }
5266 
5267 template<typename BasicJsonType, typename TupleRelated>
5268 auto from_json(BasicJsonType&& j, TupleRelated&& t)
5269 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
5270 {
5271  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5272  {
5273  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5274  }
5275 
5276  return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
5277 }
5278 
5279 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
5280  typename = enable_if_t < !std::is_constructible <
5281  typename BasicJsonType::string_t, Key >::value >>
5282 inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
5283 {
5284  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5285  {
5286  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5287  }
5288  m.clear();
5289  for (const auto& p : j)
5290  {
5291  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5292  {
5293  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5294  }
5295  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5296  }
5297 }
5298 
5299 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
5300  typename = enable_if_t < !std::is_constructible <
5301  typename BasicJsonType::string_t, Key >::value >>
5302 inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
5303 {
5304  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5305  {
5306  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5307  }
5308  m.clear();
5309  for (const auto& p : j)
5310  {
5311  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5312  {
5313  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5314  }
5315  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5316  }
5317 }
5318 
5319 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5320 template<typename BasicJsonType>
5321 inline void from_json(const BasicJsonType& j, std_fs::path& p)
5322 {
5323  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
5324  {
5325  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
5326  }
5327  const auto& s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
5328 #ifdef JSON_HAS_CPP_20
5329  p = std_fs::path(std::u8string_view(reinterpret_cast<const char8_t*>(s.data()), s.size()));
5330 #else
5331  p = std_fs::u8path(s); // accepts UTF-8 encoded std::string in C++17, deprecated in C++20
5332 #endif
5333 }
5334 #endif
5335 
5337 {
5338  template<typename BasicJsonType, typename T>
5339  auto operator()(const BasicJsonType& j, T&& val) const
5340  noexcept(noexcept(from_json(j, std::forward<T>(val))))
5341  -> decltype(from_json(j, std::forward<T>(val)))
5342  {
5343  return from_json(j, std::forward<T>(val));
5344  }
5345 };
5346 
5347 } // namespace detail
5348 
5349 #ifndef JSON_HAS_CPP_17
5353 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5354 {
5355 #endif
5356 JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
5358 #ifndef JSON_HAS_CPP_17
5359 } // namespace
5360 #endif
5361 
5363 
5364 // #include <nlohmann/detail/conversions/to_json.hpp>
5365 // __ _____ _____ _____
5366 // __| | __| | | | JSON for Modern C++
5367 // | | |__ | | | | | | version 3.12.0
5368 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5369 //
5370 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
5371 // SPDX-License-Identifier: MIT
5372 
5373 
5374 
5375 // #include <nlohmann/detail/macro_scope.hpp>
5376 // JSON_HAS_CPP_17
5377 #ifdef JSON_HAS_CPP_17
5378  #include <optional> // optional
5379 #endif
5380 
5381 #include <algorithm> // copy
5382 #include <iterator> // begin, end
5383 #include <string> // string
5384 #include <tuple> // tuple, get
5385 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
5386 #include <utility> // move, forward, declval, pair
5387 #include <valarray> // valarray
5388 #include <vector> // vector
5389 
5390 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
5391 // __ _____ _____ _____
5392 // __| | __| | | | JSON for Modern C++
5393 // | | |__ | | | | | | version 3.12.0
5394 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5395 //
5396 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
5397 // SPDX-License-Identifier: MIT
5398 
5399 
5400 
5401 #include <cstddef> // size_t
5402 #include <iterator> // forward_iterator_tag
5403 #include <tuple> // tuple_size, get, tuple_element
5404 #include <utility> // move
5405 
5406 #if JSON_HAS_RANGES
5407  #include <ranges> // enable_borrowed_range
5408 #endif
5409 
5410 // #include <nlohmann/detail/abi_macros.hpp>
5411 
5412 // #include <nlohmann/detail/meta/type_traits.hpp>
5413 
5414 // #include <nlohmann/detail/string_utils.hpp>
5415 // __ _____ _____ _____
5416 // __| | __| | | | JSON for Modern C++
5417 // | | |__ | | | | | | version 3.12.0
5418 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5419 //
5420 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
5421 // SPDX-License-Identifier: MIT
5422 
5423 
5424 
5425 #include <cstddef> // size_t
5426 #include <string> // string, to_string
5427 
5428 // #include <nlohmann/detail/abi_macros.hpp>
5429 
5430 
5432 namespace detail
5433 {
5434 
5435 template<typename StringType>
5436 void int_to_string(StringType& target, std::size_t value)
5437 {
5438  // For ADL
5439  using std::to_string;
5440  target = to_string(value);
5441 }
5442 
5443 template<typename StringType>
5444 StringType to_string(std::size_t value)
5445 {
5446  StringType result;
5447  int_to_string(result, value);
5448  return result;
5449 }
5450 
5451 } // namespace detail
5453 
5454 // #include <nlohmann/detail/value_t.hpp>
5455 
5456 
5458 namespace detail
5459 {
5460 
5461 template<typename IteratorType> class iteration_proxy_value
5462 {
5463  public:
5464  using difference_type = std::ptrdiff_t;
5466  using pointer = value_type *;
5468  using iterator_category = std::forward_iterator_tag;
5469  using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
5470 
5471  private:
5473  IteratorType anchor{};
5475  std::size_t array_index = 0;
5477  mutable std::size_t array_index_last = 0;
5479  mutable string_type array_index_str = "0";
5481  string_type empty_str{};
5482 
5483  public:
5484  explicit iteration_proxy_value() = default;
5485  explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
5486  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5487  && std::is_nothrow_default_constructible<string_type>::value)
5488  : anchor(std::move(it))
5489  , array_index(array_index_)
5490  {}
5491 
5494  // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
5496  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5497  && std::is_nothrow_move_constructible<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
5499  noexcept(std::is_nothrow_move_assignable<IteratorType>::value
5500  && std::is_nothrow_move_assignable<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
5502 
5504  const iteration_proxy_value& operator*() const
5505  {
5506  return *this;
5507  }
5508 
5511  {
5512  ++anchor;
5513  ++array_index;
5514 
5515  return *this;
5516  }
5517 
5518  iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
5519  {
5520  auto tmp = iteration_proxy_value(anchor, array_index);
5521  ++anchor;
5522  ++array_index;
5523  return tmp;
5524  }
5525 
5527  bool operator==(const iteration_proxy_value& o) const
5528  {
5529  return anchor == o.anchor;
5530  }
5531 
5533  bool operator!=(const iteration_proxy_value& o) const
5534  {
5535  return anchor != o.anchor;
5536  }
5537 
5539  const string_type& key() const
5540  {
5541  JSON_ASSERT(anchor.m_object != nullptr);
5542 
5543  switch (anchor.m_object->type())
5544  {
5545  // use integer array index as key
5546  case value_t::array:
5547  {
5548  if (array_index != array_index_last)
5549  {
5550  int_to_string( array_index_str, array_index );
5551  array_index_last = array_index;
5552  }
5553  return array_index_str;
5554  }
5555 
5556  // use key from the object
5557  case value_t::object:
5558  return anchor.key();
5559 
5560  // use an empty key for all primitive types
5561  case value_t::null:
5562  case value_t::string:
5563  case value_t::boolean:
5566  case value_t::number_float:
5567  case value_t::binary:
5568  case value_t::discarded:
5569  default:
5570  return empty_str;
5571  }
5572  }
5573 
5575  typename IteratorType::reference value() const
5576  {
5577  return anchor.value();
5578  }
5579 };
5580 
5582 template<typename IteratorType> class iteration_proxy
5583 {
5584  private:
5586  typename IteratorType::pointer container = nullptr;
5587 
5588  public:
5589  explicit iteration_proxy() = default;
5590 
5592  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
5593  : container(&cont) {}
5594 
5597  iteration_proxy(iteration_proxy&&) noexcept = default;
5598  iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
5599  ~iteration_proxy() = default;
5600 
5602  iteration_proxy_value<IteratorType> begin() const noexcept
5603  {
5604  return iteration_proxy_value<IteratorType>(container->begin());
5605  }
5606 
5609  {
5610  return iteration_proxy_value<IteratorType>(container->end());
5611  }
5612 };
5613 
5614 // Structured Bindings Support
5615 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5616 // And see https://github.com/nlohmann/json/pull/1391
5617 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
5618 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
5619 {
5620  return i.key();
5621 }
5622 // Structured Bindings Support
5623 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5624 // And see https://github.com/nlohmann/json/pull/1391
5625 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
5626 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
5627 {
5628  return i.value();
5629 }
5630 
5631 } // namespace detail
5633 
5634 // The Addition to the STD Namespace is required to add
5635 // Structured Bindings Support to the iteration_proxy_value class
5636 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5637 // And see https://github.com/nlohmann/json/pull/1391
5638 namespace std
5639 {
5640 
5641 #if defined(__clang__)
5642  // Fix: https://github.com/nlohmann/json/issues/1401
5643  #pragma clang diagnostic push
5644  #pragma clang diagnostic ignored "-Wmismatched-tags"
5645 #endif
5646 template<typename IteratorType>
5647 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
5648  : public std::integral_constant<std::size_t, 2> {};
5649 
5650 template<std::size_t N, typename IteratorType>
5651 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp)
5652 {
5653  public:
5654  using type = decltype(
5655  get<N>(std::declval <
5656  ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
5657 };
5658 #if defined(__clang__)
5659  #pragma clang diagnostic pop
5660 #endif
5661 
5662 } // namespace std
5663 
5664 #if JSON_HAS_RANGES
5665  template <typename IteratorType>
5666  inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
5667 #endif
5668 
5669 // #include <nlohmann/detail/meta/cpp_future.hpp>
5670 
5671 // #include <nlohmann/detail/meta/std_fs.hpp>
5672 
5673 // #include <nlohmann/detail/meta/type_traits.hpp>
5674 
5675 // #include <nlohmann/detail/value_t.hpp>
5676 
5677 
5679 namespace detail
5680 {
5681 
5683 // constructors //
5685 
5686 /*
5687  * Note all external_constructor<>::construct functions need to call
5688  * j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an
5689  * allocated value (e.g., a string). See bug issue
5690  * https://github.com/nlohmann/json/issues/2865 for more information.
5691  */
5692 
5693 template<value_t> struct external_constructor;
5694 
5695 template<>
5697 {
5698  template<typename BasicJsonType>
5699  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
5700  {
5701  j.m_data.m_value.destroy(j.m_data.m_type);
5702  j.m_data.m_type = value_t::boolean;
5703  j.m_data.m_value = b;
5704  j.assert_invariant();
5705  }
5706 };
5707 
5708 template<>
5710 {
5711  template<typename BasicJsonType>
5712  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
5713  {
5714  j.m_data.m_value.destroy(j.m_data.m_type);
5715  j.m_data.m_type = value_t::string;
5716  j.m_data.m_value = s;
5717  j.assert_invariant();
5718  }
5719 
5720  template<typename BasicJsonType>
5721  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5722  {
5723  j.m_data.m_value.destroy(j.m_data.m_type);
5724  j.m_data.m_type = value_t::string;
5725  j.m_data.m_value = std::move(s);
5726  j.assert_invariant();
5727  }
5728 
5729  template < typename BasicJsonType, typename CompatibleStringType,
5731  int > = 0 >
5732  static void construct(BasicJsonType& j, const CompatibleStringType& str)
5733  {
5734  j.m_data.m_value.destroy(j.m_data.m_type);
5735  j.m_data.m_type = value_t::string;
5736  j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
5737  j.assert_invariant();
5738  }
5739 };
5740 
5741 template<>
5743 {
5744  template<typename BasicJsonType>
5745  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
5746  {
5747  j.m_data.m_value.destroy(j.m_data.m_type);
5748  j.m_data.m_type = value_t::binary;
5749  j.m_data.m_value = typename BasicJsonType::binary_t(b);
5750  j.assert_invariant();
5751  }
5752 
5753  template<typename BasicJsonType>
5754  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
5755  {
5756  j.m_data.m_value.destroy(j.m_data.m_type);
5757  j.m_data.m_type = value_t::binary;
5758  j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));
5759  j.assert_invariant();
5760  }
5761 };
5762 
5763 template<>
5765 {
5766  template<typename BasicJsonType>
5767  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
5768  {
5769  j.m_data.m_value.destroy(j.m_data.m_type);
5770  j.m_data.m_type = value_t::number_float;
5771  j.m_data.m_value = val;
5772  j.assert_invariant();
5773  }
5774 };
5775 
5776 template<>
5778 {
5779  template<typename BasicJsonType>
5780  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
5781  {
5782  j.m_data.m_value.destroy(j.m_data.m_type);
5783  j.m_data.m_type = value_t::number_unsigned;
5784  j.m_data.m_value = val;
5785  j.assert_invariant();
5786  }
5787 };
5788 
5789 template<>
5791 {
5792  template<typename BasicJsonType>
5793  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
5794  {
5795  j.m_data.m_value.destroy(j.m_data.m_type);
5796  j.m_data.m_type = value_t::number_integer;
5797  j.m_data.m_value = val;
5798  j.assert_invariant();
5799  }
5800 };
5801 
5802 template<>
5804 {
5805  template<typename BasicJsonType>
5806  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
5807  {
5808  j.m_data.m_value.destroy(j.m_data.m_type);
5809  j.m_data.m_type = value_t::array;
5810  j.m_data.m_value = arr;
5811  j.set_parents();
5812  j.assert_invariant();
5813  }
5814 
5815  template<typename BasicJsonType>
5816  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5817  {
5818  j.m_data.m_value.destroy(j.m_data.m_type);
5819  j.m_data.m_type = value_t::array;
5820  j.m_data.m_value = std::move(arr);
5821  j.set_parents();
5822  j.assert_invariant();
5823  }
5824 
5825  template < typename BasicJsonType, typename CompatibleArrayType,
5827  int > = 0 >
5828  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
5829  {
5830  using std::begin;
5831  using std::end;
5832 
5833  j.m_data.m_value.destroy(j.m_data.m_type);
5834  j.m_data.m_type = value_t::array;
5835  j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
5836  j.set_parents();
5837  j.assert_invariant();
5838  }
5839 
5840  template<typename BasicJsonType>
5841  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
5842  {
5843  j.m_data.m_value.destroy(j.m_data.m_type);
5844  j.m_data.m_type = value_t::array;
5845  j.m_data.m_value = value_t::array;
5846  j.m_data.m_value.array->reserve(arr.size());
5847  for (const bool x : arr)
5848  {
5849  j.m_data.m_value.array->push_back(x);
5850  j.set_parent(j.m_data.m_value.array->back());
5851  }
5852  j.assert_invariant();
5853  }
5854 
5855  template<typename BasicJsonType, typename T,
5857  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
5858  {
5859  j.m_data.m_value.destroy(j.m_data.m_type);
5860  j.m_data.m_type = value_t::array;
5861  j.m_data.m_value = value_t::array;
5862  j.m_data.m_value.array->resize(arr.size());
5863  if (arr.size() > 0)
5864  {
5865  std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin());
5866  }
5867  j.set_parents();
5868  j.assert_invariant();
5869  }
5870 };
5871 
5872 template<>
5874 {
5875  template<typename BasicJsonType>
5876  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5877  {
5878  j.m_data.m_value.destroy(j.m_data.m_type);
5879  j.m_data.m_type = value_t::object;
5880  j.m_data.m_value = obj;
5881  j.set_parents();
5882  j.assert_invariant();
5883  }
5884 
5885  template<typename BasicJsonType>
5886  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5887  {
5888  j.m_data.m_value.destroy(j.m_data.m_type);
5889  j.m_data.m_type = value_t::object;
5890  j.m_data.m_value = std::move(obj);
5891  j.set_parents();
5892  j.assert_invariant();
5893  }
5894 
5895  template < typename BasicJsonType, typename CompatibleObjectType,
5897  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5898  {
5899  using std::begin;
5900  using std::end;
5901 
5902  j.m_data.m_value.destroy(j.m_data.m_type);
5903  j.m_data.m_type = value_t::object;
5904  j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5905  j.set_parents();
5906  j.assert_invariant();
5907  }
5908 };
5909 
5911 // to_json //
5913 
5914 #ifdef JSON_HAS_CPP_17
5915 template<typename BasicJsonType, typename T,
5916  enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
5917 void to_json(BasicJsonType& j, const std::optional<T>& opt)
5918 {
5919  if (opt.has_value())
5920  {
5921  j = *opt;
5922  }
5923  else
5924  {
5925  j = nullptr;
5926  }
5927 }
5928 #endif
5929 
5930 template<typename BasicJsonType, typename T,
5931  enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
5932 inline void to_json(BasicJsonType& j, T b) noexcept
5933 {
5935 }
5936 
5937 template < typename BasicJsonType, typename BoolRef,
5938  enable_if_t <
5939  ((std::is_same<std::vector<bool>::reference, BoolRef>::value
5940  && !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)
5941  || (std::is_same<std::vector<bool>::const_reference, BoolRef>::value
5942  && !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,
5943  typename BasicJsonType::boolean_t >::value))
5944  && std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int > = 0 >
5945 inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
5946 {
5947  external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
5948 }
5949 
5950 template<typename BasicJsonType, typename CompatibleString,
5951  enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
5952 inline void to_json(BasicJsonType& j, const CompatibleString& s)
5953 {
5955 }
5956 
5957 template<typename BasicJsonType>
5958 inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5959 {
5961 }
5962 
5963 template<typename BasicJsonType, typename FloatType,
5964  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
5965 inline void to_json(BasicJsonType& j, FloatType val) noexcept
5966 {
5967  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5968 }
5969 
5970 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5971  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
5972 inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5973 {
5974  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5975 }
5976 
5977 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5978  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
5979 inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5980 {
5981  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5982 }
5983 
5984 #if !JSON_DISABLE_ENUM_SERIALIZATION
5985 template<typename BasicJsonType, typename EnumType,
5986  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
5987 inline void to_json(BasicJsonType& j, EnumType e) noexcept
5988 {
5989  using underlying_type = typename std::underlying_type<EnumType>::type;
5990  static constexpr value_t integral_value_t = std::is_unsigned<underlying_type>::value ? value_t::number_unsigned : value_t::number_integer;
5991  external_constructor<integral_value_t>::construct(j, static_cast<underlying_type>(e));
5992 }
5993 #endif // JSON_DISABLE_ENUM_SERIALIZATION
5994 
5995 template<typename BasicJsonType>
5996 inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
5997 {
5999 }
6000 
6001 template < typename BasicJsonType, typename CompatibleArrayType,
6002  enable_if_t < is_compatible_array_type<BasicJsonType,
6003  CompatibleArrayType>::value&&
6004  !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
6006  !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
6007  !is_basic_json<CompatibleArrayType>::value,
6008  int > = 0 >
6009 inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
6010 {
6012 }
6013 
6014 template<typename BasicJsonType>
6015 inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
6016 {
6018 }
6019 
6020 template<typename BasicJsonType, typename T,
6021  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
6022 inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
6023 {
6025 }
6026 
6027 template<typename BasicJsonType>
6028 inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
6029 {
6031 }
6032 
6033 template < typename BasicJsonType, typename CompatibleObjectType,
6034  enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
6035 inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
6036 {
6038 }
6039 
6040 template<typename BasicJsonType>
6041 inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
6042 {
6044 }
6045 
6046 template <
6047  typename BasicJsonType, typename T, std::size_t N,
6048  enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
6049  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
6050  int > = 0 >
6051 inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
6052 {
6054 }
6055 
6056 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
6057 inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
6058 {
6059  j = { p.first, p.second };
6060 }
6061 
6062 // for https://github.com/nlohmann/json/pull/1134
6063 template<typename BasicJsonType, typename T,
6064  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
6065 inline void to_json(BasicJsonType& j, const T& b)
6066 {
6067  j = { {b.key(), b.value()} };
6068 }
6069 
6070 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
6071 inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
6072 {
6073  j = { std::get<Idx>(t)... };
6074 }
6075 
6076 template<typename BasicJsonType, typename Tuple>
6077 inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& /*unused*/, index_sequence<> /*unused*/)
6078 {
6079  using array_t = typename BasicJsonType::array_t;
6080  j = array_t();
6081 }
6082 
6083 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
6084 inline void to_json(BasicJsonType& j, const T& t)
6085 {
6086  to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
6087 }
6088 
6089 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
6090 template<typename BasicJsonType>
6091 inline void to_json(BasicJsonType& j, const std_fs::path& p)
6092 {
6093 #ifdef JSON_HAS_CPP_20
6094  const std::u8string s = p.u8string();
6095  j = std::string(s.begin(), s.end());
6096 #else
6097  j = p.u8string(); // returns std::string in C++17
6098 #endif
6099 }
6100 #endif
6101 
6103 {
6104  template<typename BasicJsonType, typename T>
6105  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
6106  -> decltype(to_json(j, std::forward<T>(val)), void())
6107  {
6108  return to_json(j, std::forward<T>(val));
6109  }
6110 };
6111 } // namespace detail
6112 
6113 #ifndef JSON_HAS_CPP_17
6117 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
6118 {
6119 #endif
6120 JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
6122 #ifndef JSON_HAS_CPP_17
6123 } // namespace
6124 #endif
6125 
6127 
6128 // #include <nlohmann/detail/meta/identity_tag.hpp>
6129 
6130 
6132 
6134 template<typename ValueType, typename>
6136 {
6139  template<typename BasicJsonType, typename TargetType = ValueType>
6140  static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
6141  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
6142  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
6143  {
6144  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
6145  }
6146 
6149  template<typename BasicJsonType, typename TargetType = ValueType>
6150  static auto from_json(BasicJsonType && j) noexcept(
6151  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
6152  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
6153  {
6154  return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
6155  }
6156 
6159  template<typename BasicJsonType, typename TargetType = ValueType>
6160  static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
6161  noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
6162  -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
6163  {
6164  ::nlohmann::to_json(j, std::forward<TargetType>(val));
6165  }
6166 };
6167 
6169 
6170 // #include <nlohmann/byte_container_with_subtype.hpp>
6171 // __ _____ _____ _____
6172 // __| | __| | | | JSON for Modern C++
6173 // | | |__ | | | | | | version 3.12.0
6174 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6175 //
6176 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
6177 // SPDX-License-Identifier: MIT
6178 
6179 
6180 
6181 #include <cstdint> // uint8_t, uint64_t
6182 #include <tuple> // tie
6183 #include <utility> // move
6184 
6185 // #include <nlohmann/detail/abi_macros.hpp>
6186 
6187 
6189 
6192 template<typename BinaryType>
6193 class byte_container_with_subtype : public BinaryType
6194 {
6195  public:
6196  using container_type = BinaryType;
6197  using subtype_type = std::uint64_t;
6198 
6201  : container_type()
6202  {}
6203 
6206  : container_type(b)
6207  {}
6208 
6210  byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
6211  : container_type(std::move(b))
6212  {}
6213 
6215  byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
6216  : container_type(b)
6217  , m_subtype(subtype_)
6218  , m_has_subtype(true)
6219  {}
6220 
6222  byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
6223  : container_type(std::move(b))
6224  , m_subtype(subtype_)
6225  , m_has_subtype(true)
6226  {}
6227 
6229  {
6230  return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
6231  std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
6232  }
6233 
6235  {
6236  return !(rhs == *this);
6237  }
6238 
6241  void set_subtype(subtype_type subtype_) noexcept
6242  {
6243  m_subtype = subtype_;
6244  m_has_subtype = true;
6245  }
6246 
6249  constexpr subtype_type subtype() const noexcept
6250  {
6251  return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
6252  }
6253 
6256  constexpr bool has_subtype() const noexcept
6257  {
6258  return m_has_subtype;
6259  }
6260 
6263  void clear_subtype() noexcept
6264  {
6265  m_subtype = 0;
6266  m_has_subtype = false;
6267  }
6268 
6269  private:
6270  subtype_type m_subtype = 0;
6271  bool m_has_subtype = false;
6272 };
6273 
6275 
6276 // #include <nlohmann/detail/conversions/from_json.hpp>
6277 
6278 // #include <nlohmann/detail/conversions/to_json.hpp>
6279 
6280 // #include <nlohmann/detail/exceptions.hpp>
6281 
6282 // #include <nlohmann/detail/hash.hpp>
6283 // __ _____ _____ _____
6284 // __| | __| | | | JSON for Modern C++
6285 // | | |__ | | | | | | version 3.12.0
6286 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6287 //
6288 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
6289 // SPDX-License-Identifier: MIT
6290 
6291 
6292 
6293 #include <cstdint> // uint8_t
6294 #include <cstddef> // size_t
6295 #include <functional> // hash
6296 
6297 // #include <nlohmann/detail/abi_macros.hpp>
6298 
6299 // #include <nlohmann/detail/value_t.hpp>
6300 
6301 
6303 namespace detail
6304 {
6305 
6306 // boost::hash_combine
6307 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
6308 {
6309  seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
6310  return seed;
6311 }
6312 
6324 template<typename BasicJsonType>
6325 std::size_t hash(const BasicJsonType& j)
6326 {
6327  using string_t = typename BasicJsonType::string_t;
6328  using number_integer_t = typename BasicJsonType::number_integer_t;
6329  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6330  using number_float_t = typename BasicJsonType::number_float_t;
6331 
6332  const auto type = static_cast<std::size_t>(j.type());
6333  switch (j.type())
6334  {
6335  case BasicJsonType::value_t::null:
6336  case BasicJsonType::value_t::discarded:
6337  {
6338  return combine(type, 0);
6339  }
6340 
6341  case BasicJsonType::value_t::object:
6342  {
6343  auto seed = combine(type, j.size());
6344  for (const auto& element : j.items())
6345  {
6346  const auto h = std::hash<string_t> {}(element.key());
6347  seed = combine(seed, h);
6348  seed = combine(seed, hash(element.value()));
6349  }
6350  return seed;
6351  }
6352 
6353  case BasicJsonType::value_t::array:
6354  {
6355  auto seed = combine(type, j.size());
6356  for (const auto& element : j)
6357  {
6358  seed = combine(seed, hash(element));
6359  }
6360  return seed;
6361  }
6362 
6363  case BasicJsonType::value_t::string:
6364  {
6365  const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
6366  return combine(type, h);
6367  }
6368 
6369  case BasicJsonType::value_t::boolean:
6370  {
6371  const auto h = std::hash<bool> {}(j.template get<bool>());
6372  return combine(type, h);
6373  }
6374 
6375  case BasicJsonType::value_t::number_integer:
6376  {
6377  const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
6378  return combine(type, h);
6379  }
6380 
6381  case BasicJsonType::value_t::number_unsigned:
6382  {
6383  const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
6384  return combine(type, h);
6385  }
6386 
6387  case BasicJsonType::value_t::number_float:
6388  {
6389  const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
6390  return combine(type, h);
6391  }
6392 
6393  case BasicJsonType::value_t::binary:
6394  {
6395  auto seed = combine(type, j.get_binary().size());
6396  const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
6397  seed = combine(seed, h);
6398  seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
6399  for (const auto byte : j.get_binary())
6400  {
6401  seed = combine(seed, std::hash<std::uint8_t> {}(byte));
6402  }
6403  return seed;
6404  }
6405 
6406  default: // LCOV_EXCL_LINE
6407  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
6408  return 0; // LCOV_EXCL_LINE
6409  }
6410 }
6411 
6412 } // namespace detail
6414 
6415 // #include <nlohmann/detail/input/binary_reader.hpp>
6416 // __ _____ _____ _____
6417 // __| | __| | | | JSON for Modern C++
6418 // | | |__ | | | | | | version 3.12.0
6419 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6420 //
6421 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
6422 // SPDX-License-Identifier: MIT
6423 
6424 
6425 
6426 #include <algorithm> // generate_n
6427 #include <array> // array
6428 #include <cmath> // ldexp
6429 #include <cstddef> // size_t
6430 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
6431 #include <cstdio> // snprintf
6432 #include <cstring> // memcpy
6433 #include <iterator> // back_inserter
6434 #include <limits> // numeric_limits
6435 #include <string> // char_traits, string
6436 #include <utility> // make_pair, move
6437 #include <vector> // vector
6438 #ifdef __cpp_lib_byteswap
6439  #include <bit> //byteswap
6440 #endif
6441 
6442 // #include <nlohmann/detail/exceptions.hpp>
6443 
6444 // #include <nlohmann/detail/input/input_adapters.hpp>
6445 // __ _____ _____ _____
6446 // __| | __| | | | JSON for Modern C++
6447 // | | |__ | | | | | | version 3.12.0
6448 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
6449 //
6450 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
6451 // SPDX-License-Identifier: MIT
6452 
6453 
6454 
6455 #include <array> // array
6456 #include <cstddef> // size_t
6457 #include <cstring> // strlen
6458 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
6459 #include <memory> // shared_ptr, make_shared, addressof
6460 #include <numeric> // accumulate
6461 #include <string> // string, char_traits
6462 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
6463 #include <utility> // pair, declval
6464 
6465 #ifndef JSON_NO_IO
6466  #include <cstdio> // FILE *
6467  #include <istream> // istream
6468 #endif // JSON_NO_IO
6469 
6470 // #include <nlohmann/detail/exceptions.hpp>
6471 
6472 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
6473 
6474 // #include <nlohmann/detail/macro_scope.hpp>
6475 
6476 // #include <nlohmann/detail/meta/type_traits.hpp>
6477 
6478 
6480 namespace detail
6481 {
6482 
6485 
6487 // input adapters //
6489 
6490 #ifndef JSON_NO_IO
6496 {
6497  public:
6498  using char_type = char;
6499 
6501  explicit file_input_adapter(std::FILE* f) noexcept
6502  : m_file(f)
6503  {
6504  JSON_ASSERT(m_file != nullptr);
6505  }
6506 
6507  // make class move-only
6510  file_input_adapter& operator=(const file_input_adapter&) = delete;
6511  file_input_adapter& operator=(file_input_adapter&&) = delete;
6512  ~file_input_adapter() = default;
6513 
6514  std::char_traits<char>::int_type get_character() noexcept
6515  {
6516  return std::fgetc(m_file);
6517  }
6518 
6519  // returns the number of characters successfully read
6520  template<class T>
6521  std::size_t get_elements(T* dest, std::size_t count = 1)
6522  {
6523  return fread(dest, 1, sizeof(T) * count, m_file);
6524  }
6525 
6526  private:
6528  std::FILE* m_file;
6529 };
6530 
6541 {
6542  public:
6543  using char_type = char;
6544 
6546  {
6547  // clear stream flags; we use underlying streambuf I/O, do not
6548  // maintain ifstream flags, except eof
6549  if (is != nullptr)
6550  {
6551  is->clear(is->rdstate() & std::ios::eofbit);
6552  }
6553  }
6554 
6555  explicit input_stream_adapter(std::istream& i)
6556  : is(&i), sb(i.rdbuf())
6557  {}
6558 
6559  // delete because of pointer members
6563 
6565  : is(rhs.is), sb(rhs.sb)
6566  {
6567  rhs.is = nullptr;
6568  rhs.sb = nullptr;
6569  }
6570 
6571  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
6572  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
6573  // end up as the same value, e.g. 0xFFFFFFFF.
6574  std::char_traits<char>::int_type get_character()
6575  {
6576  auto res = sb->sbumpc();
6577  // set eof manually, as we don't use the istream interface.
6578  if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
6579  {
6580  is->clear(is->rdstate() | std::ios::eofbit);
6581  }
6582  return res;
6583  }
6584 
6585  template<class T>
6586  std::size_t get_elements(T* dest, std::size_t count = 1)
6587  {
6588  auto res = static_cast<std::size_t>(sb->sgetn(reinterpret_cast<char*>(dest), static_cast<std::streamsize>(count * sizeof(T))));
6589  if (JSON_HEDLEY_UNLIKELY(res < count * sizeof(T)))
6590  {
6591  is->clear(is->rdstate() | std::ios::eofbit);
6592  }
6593  return res;
6594  }
6595 
6596  private:
6598  std::istream* is = nullptr;
6599  std::streambuf* sb = nullptr;
6600 };
6601 #endif // JSON_NO_IO
6602 
6603 // General-purpose iterator-based adapter. It might not be as fast as
6604 // theoretically possible for some containers, but it is extremely versatile.
6605 template<typename IteratorType>
6607 {
6608  public:
6609  using char_type = typename std::iterator_traits<IteratorType>::value_type;
6610 
6611  iterator_input_adapter(IteratorType first, IteratorType last)
6612  : current(std::move(first)), end(std::move(last))
6613  {}
6614 
6616  {
6617  if (JSON_HEDLEY_LIKELY(current != end))
6618  {
6619  auto result = char_traits<char_type>::to_int_type(*current);
6620  std::advance(current, 1);
6621  return result;
6622  }
6623 
6624  return char_traits<char_type>::eof();
6625  }
6626 
6627  // for general iterators, we cannot really do something better than falling back to processing the range one-by-one
6628  template<class T>
6629  std::size_t get_elements(T* dest, std::size_t count = 1)
6630  {
6631  auto* ptr = reinterpret_cast<char*>(dest);
6632  for (std::size_t read_index = 0; read_index < count * sizeof(T); ++read_index)
6633  {
6634  if (JSON_HEDLEY_LIKELY(current != end))
6635  {
6636  ptr[read_index] = static_cast<char>(*current);
6637  std::advance(current, 1);
6638  }
6639  else
6640  {
6641  return read_index;
6642  }
6643  }
6644  return count * sizeof(T);
6645  }
6646 
6647  private:
6648  IteratorType current;
6649  IteratorType end;
6650 
6651  template<typename BaseInputAdapter, size_t T>
6653 
6654  bool empty() const
6655  {
6656  return current == end;
6657  }
6658 };
6659 
6660 template<typename BaseInputAdapter, size_t T>
6662 
6663 template<typename BaseInputAdapter>
6664 struct wide_string_input_helper<BaseInputAdapter, 4>
6665 {
6666  // UTF-32
6667  static void fill_buffer(BaseInputAdapter& input,
6668  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6669  size_t& utf8_bytes_index,
6670  size_t& utf8_bytes_filled)
6671  {
6672  utf8_bytes_index = 0;
6673 
6674  if (JSON_HEDLEY_UNLIKELY(input.empty()))
6675  {
6676  utf8_bytes[0] = std::char_traits<char>::eof();
6677  utf8_bytes_filled = 1;
6678  }
6679  else
6680  {
6681  // get the current character
6682  const auto wc = input.get_character();
6683 
6684  // UTF-32 to UTF-8 encoding
6685  if (wc < 0x80)
6686  {
6687  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6688  utf8_bytes_filled = 1;
6689  }
6690  else if (wc <= 0x7FF)
6691  {
6692  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
6693  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6694  utf8_bytes_filled = 2;
6695  }
6696  else if (wc <= 0xFFFF)
6697  {
6698  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
6699  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6700  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6701  utf8_bytes_filled = 3;
6702  }
6703  else if (wc <= 0x10FFFF)
6704  {
6705  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
6706  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
6707  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6708  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6709  utf8_bytes_filled = 4;
6710  }
6711  else
6712  {
6713  // unknown character
6714  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6715  utf8_bytes_filled = 1;
6716  }
6717  }
6718  }
6719 };
6720 
6721 template<typename BaseInputAdapter>
6722 struct wide_string_input_helper<BaseInputAdapter, 2>
6723 {
6724  // UTF-16
6725  static void fill_buffer(BaseInputAdapter& input,
6726  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6727  size_t& utf8_bytes_index,
6728  size_t& utf8_bytes_filled)
6729  {
6730  utf8_bytes_index = 0;
6731 
6732  if (JSON_HEDLEY_UNLIKELY(input.empty()))
6733  {
6734  utf8_bytes[0] = std::char_traits<char>::eof();
6735  utf8_bytes_filled = 1;
6736  }
6737  else
6738  {
6739  // get the current character
6740  const auto wc = input.get_character();
6741 
6742  // UTF-16 to UTF-8 encoding
6743  if (wc < 0x80)
6744  {
6745  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6746  utf8_bytes_filled = 1;
6747  }
6748  else if (wc <= 0x7FF)
6749  {
6750  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
6751  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6752  utf8_bytes_filled = 2;
6753  }
6754  else if (0xD800 > wc || wc >= 0xE000)
6755  {
6756  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
6757  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6758  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6759  utf8_bytes_filled = 3;
6760  }
6761  else
6762  {
6763  if (JSON_HEDLEY_UNLIKELY(!input.empty()))
6764  {
6765  const auto wc2 = static_cast<unsigned int>(input.get_character());
6766  const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
6767  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
6768  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
6769  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
6770  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
6771  utf8_bytes_filled = 4;
6772  }
6773  else
6774  {
6775  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6776  utf8_bytes_filled = 1;
6777  }
6778  }
6779  }
6780  }
6781 };
6782 
6783 // Wraps another input adapter to convert wide character types into individual bytes.
6784 template<typename BaseInputAdapter, typename WideCharType>
6786 {
6787  public:
6788  using char_type = char;
6789 
6790  wide_string_input_adapter(BaseInputAdapter base)
6791  : base_adapter(base) {}
6792 
6793  typename std::char_traits<char>::int_type get_character() noexcept
6794  {
6795  // check if buffer needs to be filled
6796  if (utf8_bytes_index == utf8_bytes_filled)
6797  {
6798  fill_buffer<sizeof(WideCharType)>();
6799 
6800  JSON_ASSERT(utf8_bytes_filled > 0);
6801  JSON_ASSERT(utf8_bytes_index == 0);
6802  }
6803 
6804  // use buffer
6805  JSON_ASSERT(utf8_bytes_filled > 0);
6806  JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
6807  return utf8_bytes[utf8_bytes_index++];
6808  }
6809 
6810  // parsing binary with wchar doesn't make sense, but since the parsing mode can be runtime, we need something here
6811  template<class T>
6812  std::size_t get_elements(T* /*dest*/, std::size_t /*count*/ = 1)
6813  {
6814  JSON_THROW(parse_error::create(112, 1, "wide string type cannot be interpreted as binary data", nullptr));
6815  }
6816 
6817  private:
6818  BaseInputAdapter base_adapter;
6819 
6820  template<size_t T>
6821  void fill_buffer()
6822  {
6823  wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
6824  }
6825 
6827  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
6828 
6830  std::size_t utf8_bytes_index = 0;
6832  std::size_t utf8_bytes_filled = 0;
6833 };
6834 
6835 template<typename IteratorType, typename Enable = void>
6837 {
6838  using iterator_type = IteratorType;
6839  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6841 
6842  static adapter_type create(IteratorType first, IteratorType last)
6843  {
6844  return adapter_type(std::move(first), std::move(last));
6845  }
6846 };
6847 
6848 template<typename T>
6850 {
6851  using value_type = typename std::iterator_traits<T>::value_type;
6852  enum
6853  {
6854  value = sizeof(value_type) > 1
6855  };
6856 };
6857 
6858 template<typename IteratorType>
6860 {
6861  using iterator_type = IteratorType;
6862  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6865 
6866  static adapter_type create(IteratorType first, IteratorType last)
6867  {
6868  return adapter_type(base_adapter_type(std::move(first), std::move(last)));
6869  }
6870 };
6871 
6872 // General purpose iterator-based input
6873 template<typename IteratorType>
6874 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
6875 {
6876  using factory_type = iterator_input_adapter_factory<IteratorType>;
6877  return factory_type::create(first, last);
6878 }
6879 
6880 // Convenience shorthand from container to iterator
6881 // Enables ADL on begin(container) and end(container)
6882 // Encloses the using declarations in namespace for not to leak them to outside scope
6883 
6884 namespace container_input_adapter_factory_impl
6885 {
6886 
6887 using std::begin;
6888 using std::end;
6889 
6890 template<typename ContainerType, typename Enable = void>
6892 
6893 template<typename ContainerType>
6894 struct container_input_adapter_factory< ContainerType,
6895  void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
6896  {
6897  using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
6898 
6899  static adapter_type create(const ContainerType& container)
6900 {
6901  return input_adapter(begin(container), end(container));
6902 }
6903  };
6904 
6905 } // namespace container_input_adapter_factory_impl
6906 
6907 template<typename ContainerType>
6909 {
6911 }
6912 
6913 // specialization for std::string
6914 using string_input_adapter_type = decltype(input_adapter(std::declval<std::string>()));
6915 
6916 #ifndef JSON_NO_IO
6917 // Special cases with fast paths
6918 inline file_input_adapter input_adapter(std::FILE* file)
6919 {
6920  if (file == nullptr)
6921  {
6922  JSON_THROW(parse_error::create(101, 0, "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
6923  }
6924  return file_input_adapter(file);
6925 }
6926 
6927 inline input_stream_adapter input_adapter(std::istream& stream)
6928 {
6929  return input_stream_adapter(stream);
6930 }
6931 
6932 inline input_stream_adapter input_adapter(std::istream&& stream)
6933 {
6934  return input_stream_adapter(stream);
6935 }
6936 #endif // JSON_NO_IO
6937 
6938 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
6939 
6940 // Null-delimited strings, and the like.
6941 template < typename CharT,
6942  typename std::enable_if <
6943  std::is_pointer<CharT>::value&&
6944  !std::is_array<CharT>::value&&
6945  std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
6946  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6947  int >::type = 0 >
6949 {
6950  if (b == nullptr)
6951  {
6952  JSON_THROW(parse_error::create(101, 0, "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
6953  }
6954  auto length = std::strlen(reinterpret_cast<const char*>(b));
6955  const auto* ptr = reinterpret_cast<const char*>(b);
6956  return input_adapter(ptr, ptr + length); // cppcheck-suppress[nullPointerArithmeticRedundantCheck]
6957 }
6958 
6959 template<typename T, std::size_t N>
6960 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
6961 {
6962  return input_adapter(array, array + N);
6963 }
6964 
6965 // This class only handles inputs of input_buffer_adapter type.
6966 // It's required so that expressions like {ptr, len} can be implicitly cast
6967 // to the correct adapter.
6969 {
6970  public:
6971  template < typename CharT,
6972  typename std::enable_if <
6973  std::is_pointer<CharT>::value&&
6974  std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
6975  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6976  int >::type = 0 >
6977  span_input_adapter(CharT b, std::size_t l)
6978  : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
6979 
6980  template<class IteratorType,
6981  typename std::enable_if<
6982  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
6983  int>::type = 0>
6984  span_input_adapter(IteratorType first, IteratorType last)
6985  : ia(input_adapter(first, last)) {}
6986 
6988  {
6989  return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
6990  }
6991 
6992  private:
6994 };
6995 
6996 } // namespace detail
6998 
6999 // #include <nlohmann/detail/input/json_sax.hpp>
7000 // __ _____ _____ _____
7001 // __| | __| | | | JSON for Modern C++
7002 // | | |__ | | | | | | version 3.12.0
7003 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
7004 //
7005 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
7006 // SPDX-License-Identifier: MIT
7007 
7008 
7009 
7010 #include <cstddef>
7011 #include <string> // string
7012 #include <type_traits> // enable_if_t
7013 #include <utility> // move
7014 #include <vector> // vector
7015 
7016 // #include <nlohmann/detail/exceptions.hpp>
7017 
7018 // #include <nlohmann/detail/input/lexer.hpp>
7019 // __ _____ _____ _____
7020 // __| | __| | | | JSON for Modern C++
7021 // | | |__ | | | | | | version 3.12.0
7022 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
7023 //
7024 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
7025 // SPDX-License-Identifier: MIT
7026 
7027 
7028 
7029 #include <array> // array
7030 #include <clocale> // localeconv
7031 #include <cstddef> // size_t
7032 #include <cstdio> // snprintf
7033 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
7034 #include <initializer_list> // initializer_list
7035 #include <string> // char_traits, string
7036 #include <utility> // move
7037 #include <vector> // vector
7038 
7039 // #include <nlohmann/detail/input/input_adapters.hpp>
7040 
7041 // #include <nlohmann/detail/input/position_t.hpp>
7042 
7043 // #include <nlohmann/detail/macro_scope.hpp>
7044 
7045 // #include <nlohmann/detail/meta/type_traits.hpp>
7046 
7047 
7049 namespace detail
7050 {
7051 
7053 // lexer //
7055 
7056 template<typename BasicJsonType>
7058 {
7059  public:
7061  enum class token_type
7062  {
7063  uninitialized,
7064  literal_true,
7065  literal_false,
7066  literal_null,
7067  value_string,
7068  value_unsigned,
7069  value_integer,
7070  value_float,
7071  begin_array,
7072  begin_object,
7073  end_array,
7074  end_object,
7075  name_separator,
7076  value_separator,
7077  parse_error,
7078  end_of_input,
7080  };
7081 
7085  static const char* token_type_name(const token_type t) noexcept
7086  {
7087  switch (t)
7088  {
7090  return "<uninitialized>";
7092  return "true literal";
7094  return "false literal";
7096  return "null literal";
7098  return "string literal";
7102  return "number literal";
7104  return "'['";
7106  return "'{'";
7107  case token_type::end_array:
7108  return "']'";
7110  return "'}'";
7112  return "':'";
7114  return "','";
7116  return "<parse error>";
7118  return "end of input";
7120  return "'[', '{', or a literal";
7121  // LCOV_EXCL_START
7122  default: // catch non-enum values
7123  return "unknown token";
7124  // LCOV_EXCL_STOP
7125  }
7126  }
7127 };
7133 template<typename BasicJsonType, typename InputAdapterType>
7134 class lexer : public lexer_base<BasicJsonType>
7135 {
7136  using number_integer_t = typename BasicJsonType::number_integer_t;
7137  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7138  using number_float_t = typename BasicJsonType::number_float_t;
7139  using string_t = typename BasicJsonType::string_t;
7140  using char_type = typename InputAdapterType::char_type;
7141  using char_int_type = typename char_traits<char_type>::int_type;
7142 
7143  public:
7145 
7146  explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
7147  : ia(std::move(adapter))
7148  , ignore_comments(ignore_comments_)
7149  , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
7150  {}
7151 
7152  // delete because of pointer members
7153  lexer(const lexer&) = delete;
7154  lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7155  lexer& operator=(lexer&) = delete;
7156  lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7157  ~lexer() = default;
7158 
7159  private:
7161  // locales
7163 
7166  static char get_decimal_point() noexcept
7167  {
7168  const auto* loc = localeconv();
7169  JSON_ASSERT(loc != nullptr);
7170  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7171  }
7172 
7174  // scan functions
7176 
7192  int get_codepoint()
7193  {
7194  // this function only makes sense after reading `\u`
7195  JSON_ASSERT(current == 'u');
7196  int codepoint = 0;
7197 
7198  const auto factors = { 12u, 8u, 4u, 0u };
7199  for (const auto factor : factors)
7200  {
7201  get();
7202 
7203  if (current >= '0' && current <= '9')
7204  {
7205  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7206  }
7207  else if (current >= 'A' && current <= 'F')
7208  {
7209  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7210  }
7211  else if (current >= 'a' && current <= 'f')
7212  {
7213  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7214  }
7215  else
7216  {
7217  return -1;
7218  }
7219  }
7220 
7221  JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
7222  return codepoint;
7223  }
7224 
7240  bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
7241  {
7242  JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
7243  add(current);
7244 
7245  for (auto range = ranges.begin(); range != ranges.end(); ++range)
7246  {
7247  get();
7248  if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) // NOLINT(bugprone-inc-dec-in-conditions)
7249  {
7250  add(current);
7251  }
7252  else
7253  {
7254  error_message = "invalid string: ill-formed UTF-8 byte";
7255  return false;
7256  }
7257  }
7258 
7259  return true;
7260  }
7261 
7277  token_type scan_string()
7278  {
7279  // reset token_buffer (ignore opening quote)
7280  reset();
7281 
7282  // we entered the function by reading an open quote
7283  JSON_ASSERT(current == '\"');
7284 
7285  while (true)
7286  {
7287  // get next character
7288  switch (get())
7289  {
7290  // end of file while parsing string
7291  case char_traits<char_type>::eof():
7292  {
7293  error_message = "invalid string: missing closing quote";
7294  return token_type::parse_error;
7295  }
7296 
7297  // closing quote
7298  case '\"':
7299  {
7300  return token_type::value_string;
7301  }
7302 
7303  // escapes
7304  case '\\':
7305  {
7306  switch (get())
7307  {
7308  // quotation mark
7309  case '\"':
7310  add('\"');
7311  break;
7312  // reverse solidus
7313  case '\\':
7314  add('\\');
7315  break;
7316  // solidus
7317  case '/':
7318  add('/');
7319  break;
7320  // backspace
7321  case 'b':
7322  add('\b');
7323  break;
7324  // form feed
7325  case 'f':
7326  add('\f');
7327  break;
7328  // line feed
7329  case 'n':
7330  add('\n');
7331  break;
7332  // carriage return
7333  case 'r':
7334  add('\r');
7335  break;
7336  // tab
7337  case 't':
7338  add('\t');
7339  break;
7340 
7341  // unicode escapes
7342  case 'u':
7343  {
7344  const int codepoint1 = get_codepoint();
7345  int codepoint = codepoint1; // start with codepoint1
7346 
7347  if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7348  {
7349  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7350  return token_type::parse_error;
7351  }
7352 
7353  // check if code point is a high surrogate
7354  if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7355  {
7356  // expect next \uxxxx entry
7357  if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7358  {
7359  const int codepoint2 = get_codepoint();
7360 
7361  if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7362  {
7363  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7364  return token_type::parse_error;
7365  }
7366 
7367  // check if codepoint2 is a low surrogate
7368  if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7369  {
7370  // overwrite codepoint
7371  codepoint = static_cast<int>(
7372  // high surrogate occupies the most significant 22 bits
7373  (static_cast<unsigned int>(codepoint1) << 10u)
7374  // low surrogate occupies the least significant 15 bits
7375  + static_cast<unsigned int>(codepoint2)
7376  // there is still the 0xD800, 0xDC00 and 0x10000 noise
7377  // in the result, so we have to subtract with:
7378  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7379  - 0x35FDC00u);
7380  }
7381  else
7382  {
7383  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7384  return token_type::parse_error;
7385  }
7386  }
7387  else
7388  {
7389  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7390  return token_type::parse_error;
7391  }
7392  }
7393  else
7394  {
7395  if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7396  {
7397  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7398  return token_type::parse_error;
7399  }
7400  }
7401 
7402  // result of the above calculation yields a proper codepoint
7403  JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7404 
7405  // translate codepoint into bytes
7406  if (codepoint < 0x80)
7407  {
7408  // 1-byte characters: 0xxxxxxx (ASCII)
7409  add(static_cast<char_int_type>(codepoint));
7410  }
7411  else if (codepoint <= 0x7FF)
7412  {
7413  // 2-byte characters: 110xxxxx 10xxxxxx
7414  add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7415  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7416  }
7417  else if (codepoint <= 0xFFFF)
7418  {
7419  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7420  add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7421  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7422  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7423  }
7424  else
7425  {
7426  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7427  add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7428  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7429  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7430  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7431  }
7432 
7433  break;
7434  }
7435 
7436  // other characters after escape
7437  default:
7438  error_message = "invalid string: forbidden character after backslash";
7439  return token_type::parse_error;
7440  }
7441 
7442  break;
7443  }
7444 
7445  // invalid control characters
7446  case 0x00:
7447  {
7448  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7449  return token_type::parse_error;
7450  }
7451 
7452  case 0x01:
7453  {
7454  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7455  return token_type::parse_error;
7456  }
7457 
7458  case 0x02:
7459  {
7460  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7461  return token_type::parse_error;
7462  }
7463 
7464  case 0x03:
7465  {
7466  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7467  return token_type::parse_error;
7468  }
7469 
7470  case 0x04:
7471  {
7472  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7473  return token_type::parse_error;
7474  }
7475 
7476  case 0x05:
7477  {
7478  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7479  return token_type::parse_error;
7480  }
7481 
7482  case 0x06:
7483  {
7484  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7485  return token_type::parse_error;
7486  }
7487 
7488  case 0x07:
7489  {
7490  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7491  return token_type::parse_error;
7492  }
7493 
7494  case 0x08:
7495  {
7496  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7497  return token_type::parse_error;
7498  }
7499 
7500  case 0x09:
7501  {
7502  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7503  return token_type::parse_error;
7504  }
7505 
7506  case 0x0A:
7507  {
7508  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7509  return token_type::parse_error;
7510  }
7511 
7512  case 0x0B:
7513  {
7514  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7515  return token_type::parse_error;
7516  }
7517 
7518  case 0x0C:
7519  {
7520  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7521  return token_type::parse_error;
7522  }
7523 
7524  case 0x0D:
7525  {
7526  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7527  return token_type::parse_error;
7528  }
7529 
7530  case 0x0E:
7531  {
7532  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7533  return token_type::parse_error;
7534  }
7535 
7536  case 0x0F:
7537  {
7538  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7539  return token_type::parse_error;
7540  }
7541 
7542  case 0x10:
7543  {
7544  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7545  return token_type::parse_error;
7546  }
7547 
7548  case 0x11:
7549  {
7550  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7551  return token_type::parse_error;
7552  }
7553 
7554  case 0x12:
7555  {
7556  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7557  return token_type::parse_error;
7558  }
7559 
7560  case 0x13:
7561  {
7562  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7563  return token_type::parse_error;
7564  }
7565 
7566  case 0x14:
7567  {
7568  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7569  return token_type::parse_error;
7570  }
7571 
7572  case 0x15:
7573  {
7574  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7575  return token_type::parse_error;
7576  }
7577 
7578  case 0x16:
7579  {
7580  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7581  return token_type::parse_error;
7582  }
7583 
7584  case 0x17:
7585  {
7586  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7587  return token_type::parse_error;
7588  }
7589 
7590  case 0x18:
7591  {
7592  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7593  return token_type::parse_error;
7594  }
7595 
7596  case 0x19:
7597  {
7598  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7599  return token_type::parse_error;
7600  }
7601 
7602  case 0x1A:
7603  {
7604  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7605  return token_type::parse_error;
7606  }
7607 
7608  case 0x1B:
7609  {
7610  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7611  return token_type::parse_error;
7612  }
7613 
7614  case 0x1C:
7615  {
7616  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7617  return token_type::parse_error;
7618  }
7619 
7620  case 0x1D:
7621  {
7622  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7623  return token_type::parse_error;
7624  }
7625 
7626  case 0x1E:
7627  {
7628  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7629  return token_type::parse_error;
7630  }
7631 
7632  case 0x1F:
7633  {
7634  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7635  return token_type::parse_error;
7636  }
7637 
7638  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7639  case 0x20:
7640  case 0x21:
7641  case 0x23:
7642  case 0x24:
7643  case 0x25:
7644  case 0x26:
7645  case 0x27:
7646  case 0x28:
7647  case 0x29:
7648  case 0x2A:
7649  case 0x2B:
7650  case 0x2C:
7651  case 0x2D:
7652  case 0x2E:
7653  case 0x2F:
7654  case 0x30:
7655  case 0x31:
7656  case 0x32:
7657  case 0x33:
7658  case 0x34:
7659  case 0x35:
7660  case 0x36:
7661  case 0x37:
7662  case 0x38:
7663  case 0x39:
7664  case 0x3A:
7665  case 0x3B:
7666  case 0x3C:
7667  case 0x3D:
7668  case 0x3E:
7669  case 0x3F:
7670  case 0x40:
7671  case 0x41:
7672  case 0x42:
7673  case 0x43:
7674  case 0x44:
7675  case 0x45:
7676  case 0x46:
7677  case 0x47:
7678  case 0x48:
7679  case 0x49:
7680  case 0x4A:
7681  case 0x4B:
7682  case 0x4C:
7683  case 0x4D:
7684  case 0x4E:
7685  case 0x4F:
7686  case 0x50:
7687  case 0x51:
7688  case 0x52:
7689  case 0x53:
7690  case 0x54:
7691  case 0x55:
7692  case 0x56:
7693  case 0x57:
7694  case 0x58:
7695  case 0x59:
7696  case 0x5A:
7697  case 0x5B:
7698  case 0x5D:
7699  case 0x5E:
7700  case 0x5F:
7701  case 0x60:
7702  case 0x61:
7703  case 0x62:
7704  case 0x63:
7705  case 0x64:
7706  case 0x65:
7707  case 0x66:
7708  case 0x67:
7709  case 0x68:
7710  case 0x69:
7711  case 0x6A:
7712  case 0x6B:
7713  case 0x6C:
7714  case 0x6D:
7715  case 0x6E:
7716  case 0x6F:
7717  case 0x70:
7718  case 0x71:
7719  case 0x72:
7720  case 0x73:
7721  case 0x74:
7722  case 0x75:
7723  case 0x76:
7724  case 0x77:
7725  case 0x78:
7726  case 0x79:
7727  case 0x7A:
7728  case 0x7B:
7729  case 0x7C:
7730  case 0x7D:
7731  case 0x7E:
7732  case 0x7F:
7733  {
7734  add(current);
7735  break;
7736  }
7737 
7738  // U+0080..U+07FF: bytes C2..DF 80..BF
7739  case 0xC2:
7740  case 0xC3:
7741  case 0xC4:
7742  case 0xC5:
7743  case 0xC6:
7744  case 0xC7:
7745  case 0xC8:
7746  case 0xC9:
7747  case 0xCA:
7748  case 0xCB:
7749  case 0xCC:
7750  case 0xCD:
7751  case 0xCE:
7752  case 0xCF:
7753  case 0xD0:
7754  case 0xD1:
7755  case 0xD2:
7756  case 0xD3:
7757  case 0xD4:
7758  case 0xD5:
7759  case 0xD6:
7760  case 0xD7:
7761  case 0xD8:
7762  case 0xD9:
7763  case 0xDA:
7764  case 0xDB:
7765  case 0xDC:
7766  case 0xDD:
7767  case 0xDE:
7768  case 0xDF:
7769  {
7770  if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7771  {
7772  return token_type::parse_error;
7773  }
7774  break;
7775  }
7776 
7777  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7778  case 0xE0:
7779  {
7780  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7781  {
7782  return token_type::parse_error;
7783  }
7784  break;
7785  }
7786 
7787  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7788  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7789  case 0xE1:
7790  case 0xE2:
7791  case 0xE3:
7792  case 0xE4:
7793  case 0xE5:
7794  case 0xE6:
7795  case 0xE7:
7796  case 0xE8:
7797  case 0xE9:
7798  case 0xEA:
7799  case 0xEB:
7800  case 0xEC:
7801  case 0xEE:
7802  case 0xEF:
7803  {
7804  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7805  {
7806  return token_type::parse_error;
7807  }
7808  break;
7809  }
7810 
7811  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7812  case 0xED:
7813  {
7814  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7815  {
7816  return token_type::parse_error;
7817  }
7818  break;
7819  }
7820 
7821  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7822  case 0xF0:
7823  {
7824  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7825  {
7826  return token_type::parse_error;
7827  }
7828  break;
7829  }
7830 
7831  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7832  case 0xF1:
7833  case 0xF2:
7834  case 0xF3:
7835  {
7836  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7837  {
7838  return token_type::parse_error;
7839  }
7840  break;
7841  }
7842 
7843  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7844  case 0xF4:
7845  {
7846  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7847  {
7848  return token_type::parse_error;
7849  }
7850  break;
7851  }
7852 
7853  // remaining bytes (80..C1 and F5..FF) are ill-formed
7854  default:
7855  {
7856  error_message = "invalid string: ill-formed UTF-8 byte";
7857  return token_type::parse_error;
7858  }
7859  }
7860  }
7861  }
7862 
7867  bool scan_comment()
7868  {
7869  switch (get())
7870  {
7871  // single-line comments skip input until a newline or EOF is read
7872  case '/':
7873  {
7874  while (true)
7875  {
7876  switch (get())
7877  {
7878  case '\n':
7879  case '\r':
7880  case char_traits<char_type>::eof():
7881  case '\0':
7882  return true;
7883 
7884  default:
7885  break;
7886  }
7887  }
7888  }
7889 
7890  // multi-line comments skip input until */ is read
7891  case '*':
7892  {
7893  while (true)
7894  {
7895  switch (get())
7896  {
7897  case char_traits<char_type>::eof():
7898  case '\0':
7899  {
7900  error_message = "invalid comment; missing closing '*/'";
7901  return false;
7902  }
7903 
7904  case '*':
7905  {
7906  switch (get())
7907  {
7908  case '/':
7909  return true;
7910 
7911  default:
7912  {
7913  unget();
7914  continue;
7915  }
7916  }
7917  }
7918 
7919  default:
7920  continue;
7921  }
7922  }
7923  }
7924 
7925  // unexpected character after reading '/'
7926  default:
7927  {
7928  error_message = "invalid comment; expecting '/' or '*' after '/'";
7929  return false;
7930  }
7931  }
7932  }
7933 
7935  static void strtof(float& f, const char* str, char** endptr) noexcept
7936  {
7937  f = std::strtof(str, endptr);
7938  }
7939 
7941  static void strtof(double& f, const char* str, char** endptr) noexcept
7942  {
7943  f = std::strtod(str, endptr);
7944  }
7945 
7947  static void strtof(long double& f, const char* str, char** endptr) noexcept
7948  {
7949  f = std::strtold(str, endptr);
7950  }
7951 
7992  token_type scan_number() // lgtm [cpp/use-of-goto] `goto` is used in this function to implement the number-parsing state machine described above. By design, any finite input will eventually reach the "done" state or return token_type::parse_error. In each intermediate state, 1 byte of the input is appended to the token_buffer vector, and only the already initialized variables token_buffer, number_type, and error_message are manipulated.
7993  {
7994  // reset token_buffer to store the number's bytes
7995  reset();
7996 
7997  // the type of the parsed number; initially set to unsigned; will be
7998  // changed if minus sign, decimal point or exponent is read
7999  token_type number_type = token_type::value_unsigned;
8000 
8001  // state (init): we just found out we need to scan a number
8002  switch (current)
8003  {
8004  case '-':
8005  {
8006  add(current);
8007  goto scan_number_minus;
8008  }
8009 
8010  case '0':
8011  {
8012  add(current);
8013  goto scan_number_zero;
8014  }
8015 
8016  case '1':
8017  case '2':
8018  case '3':
8019  case '4':
8020  case '5':
8021  case '6':
8022  case '7':
8023  case '8':
8024  case '9':
8025  {
8026  add(current);
8027  goto scan_number_any1;
8028  }
8029 
8030  // all other characters are rejected outside scan_number()
8031  default: // LCOV_EXCL_LINE
8032  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8033  }
8034 
8035 scan_number_minus:
8036  // state: we just parsed a leading minus sign
8037  number_type = token_type::value_integer;
8038  switch (get())
8039  {
8040  case '0':
8041  {
8042  add(current);
8043  goto scan_number_zero;
8044  }
8045 
8046  case '1':
8047  case '2':
8048  case '3':
8049  case '4':
8050  case '5':
8051  case '6':
8052  case '7':
8053  case '8':
8054  case '9':
8055  {
8056  add(current);
8057  goto scan_number_any1;
8058  }
8059 
8060  default:
8061  {
8062  error_message = "invalid number; expected digit after '-'";
8063  return token_type::parse_error;
8064  }
8065  }
8066 
8067 scan_number_zero:
8068  // state: we just parse a zero (maybe with a leading minus sign)
8069  switch (get())
8070  {
8071  case '.':
8072  {
8073  add(decimal_point_char);
8074  decimal_point_position = token_buffer.size() - 1;
8075  goto scan_number_decimal1;
8076  }
8077 
8078  case 'e':
8079  case 'E':
8080  {
8081  add(current);
8082  goto scan_number_exponent;
8083  }
8084 
8085  default:
8086  goto scan_number_done;
8087  }
8088 
8089 scan_number_any1:
8090  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
8091  switch (get())
8092  {
8093  case '0':
8094  case '1':
8095  case '2':
8096  case '3':
8097  case '4':
8098  case '5':
8099  case '6':
8100  case '7':
8101  case '8':
8102  case '9':
8103  {
8104  add(current);
8105  goto scan_number_any1;
8106  }
8107 
8108  case '.':
8109  {
8110  add(decimal_point_char);
8111  decimal_point_position = token_buffer.size() - 1;
8112  goto scan_number_decimal1;
8113  }
8114 
8115  case 'e':
8116  case 'E':
8117  {
8118  add(current);
8119  goto scan_number_exponent;
8120  }
8121 
8122  default:
8123  goto scan_number_done;
8124  }
8125 
8126 scan_number_decimal1:
8127  // state: we just parsed a decimal point
8128  number_type = token_type::value_float;
8129  switch (get())
8130  {
8131  case '0':
8132  case '1':
8133  case '2':
8134  case '3':
8135  case '4':
8136  case '5':
8137  case '6':
8138  case '7':
8139  case '8':
8140  case '9':
8141  {
8142  add(current);
8143  goto scan_number_decimal2;
8144  }
8145 
8146  default:
8147  {
8148  error_message = "invalid number; expected digit after '.'";
8149  return token_type::parse_error;
8150  }
8151  }
8152 
8153 scan_number_decimal2:
8154  // we just parsed at least one number after a decimal point
8155  switch (get())
8156  {
8157  case '0':
8158  case '1':
8159  case '2':
8160  case '3':
8161  case '4':
8162  case '5':
8163  case '6':
8164  case '7':
8165  case '8':
8166  case '9':
8167  {
8168  add(current);
8169  goto scan_number_decimal2;
8170  }
8171 
8172  case 'e':
8173  case 'E':
8174  {
8175  add(current);
8176  goto scan_number_exponent;
8177  }
8178 
8179  default:
8180  goto scan_number_done;
8181  }
8182 
8183 scan_number_exponent:
8184  // we just parsed an exponent
8185  number_type = token_type::value_float;
8186  switch (get())
8187  {
8188  case '+':
8189  case '-':
8190  {
8191  add(current);
8192  goto scan_number_sign;
8193  }
8194 
8195  case '0':
8196  case '1':
8197  case '2':
8198  case '3':
8199  case '4':
8200  case '5':
8201  case '6':
8202  case '7':
8203  case '8':
8204  case '9':
8205  {
8206  add(current);
8207  goto scan_number_any2;
8208  }
8209 
8210  default:
8211  {
8212  error_message =
8213  "invalid number; expected '+', '-', or digit after exponent";
8214  return token_type::parse_error;
8215  }
8216  }
8217 
8218 scan_number_sign:
8219  // we just parsed an exponent sign
8220  switch (get())
8221  {
8222  case '0':
8223  case '1':
8224  case '2':
8225  case '3':
8226  case '4':
8227  case '5':
8228  case '6':
8229  case '7':
8230  case '8':
8231  case '9':
8232  {
8233  add(current);
8234  goto scan_number_any2;
8235  }
8236 
8237  default:
8238  {
8239  error_message = "invalid number; expected digit after exponent sign";
8240  return token_type::parse_error;
8241  }
8242  }
8243 
8244 scan_number_any2:
8245  // we just parsed a number after the exponent or exponent sign
8246  switch (get())
8247  {
8248  case '0':
8249  case '1':
8250  case '2':
8251  case '3':
8252  case '4':
8253  case '5':
8254  case '6':
8255  case '7':
8256  case '8':
8257  case '9':
8258  {
8259  add(current);
8260  goto scan_number_any2;
8261  }
8262 
8263  default:
8264  goto scan_number_done;
8265  }
8266 
8267 scan_number_done:
8268  // unget the character after the number (we only read it to know that
8269  // we are done scanning a number)
8270  unget();
8271 
8272  char* endptr = nullptr; // NOLINT(misc-const-correctness,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8273  errno = 0;
8274 
8275  // try to parse integers first and fall back to floats
8276  if (number_type == token_type::value_unsigned)
8277  {
8278  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8279 
8280  // we checked the number format before
8281  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8282 
8283  if (errno != ERANGE)
8284  {
8285  value_unsigned = static_cast<number_unsigned_t>(x);
8286  if (value_unsigned == x)
8287  {
8288  return token_type::value_unsigned;
8289  }
8290  }
8291  }
8292  else if (number_type == token_type::value_integer)
8293  {
8294  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8295 
8296  // we checked the number format before
8297  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8298 
8299  if (errno != ERANGE)
8300  {
8301  value_integer = static_cast<number_integer_t>(x);
8302  if (value_integer == x)
8303  {
8304  return token_type::value_integer;
8305  }
8306  }
8307  }
8308 
8309  // this code is reached if we parse a floating-point number or if an
8310  // integer conversion above failed
8311  strtof(value_float, token_buffer.data(), &endptr);
8312 
8313  // we checked the number format before
8314  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8315 
8316  return token_type::value_float;
8317  }
8318 
8325  token_type scan_literal(const char_type* literal_text, const std::size_t length,
8326  token_type return_type)
8327  {
8328  JSON_ASSERT(char_traits<char_type>::to_char_type(current) == literal_text[0]);
8329  for (std::size_t i = 1; i < length; ++i)
8330  {
8331  if (JSON_HEDLEY_UNLIKELY(char_traits<char_type>::to_char_type(get()) != literal_text[i]))
8332  {
8333  error_message = "invalid literal";
8334  return token_type::parse_error;
8335  }
8336  }
8337  return return_type;
8338  }
8339 
8341  // input management
8343 
8345  void reset() noexcept
8346  {
8347  token_buffer.clear();
8348  token_string.clear();
8349  decimal_point_position = std::string::npos;
8350  token_string.push_back(char_traits<char_type>::to_char_type(current));
8351  }
8352 
8353  /*
8354  @brief get next character from the input
8355 
8356  This function provides the interface to the used input adapter. It does
8357  not throw in case the input reached EOF, but returns a
8358  `char_traits<char>::eof()` in that case. Stores the scanned characters
8359  for use in error messages.
8360 
8361  @return character read from the input
8362  */
8363  char_int_type get()
8364  {
8365  ++position.chars_read_total;
8366  ++position.chars_read_current_line;
8367 
8368  if (next_unget)
8369  {
8370  // just reset the next_unget variable and work with current
8371  next_unget = false;
8372  }
8373  else
8374  {
8375  current = ia.get_character();
8376  }
8377 
8378  if (JSON_HEDLEY_LIKELY(current != char_traits<char_type>::eof()))
8379  {
8380  token_string.push_back(char_traits<char_type>::to_char_type(current));
8381  }
8382 
8383  if (current == '\n')
8384  {
8385  ++position.lines_read;
8386  position.chars_read_current_line = 0;
8387  }
8388 
8389  return current;
8390  }
8391 
8400  void unget()
8401  {
8402  next_unget = true;
8403 
8404  --position.chars_read_total;
8405 
8406  // in case we "unget" a newline, we have to also decrement the lines_read
8407  if (position.chars_read_current_line == 0)
8408  {
8409  if (position.lines_read > 0)
8410  {
8411  --position.lines_read;
8412  }
8413  }
8414  else
8415  {
8416  --position.chars_read_current_line;
8417  }
8418 
8419  if (JSON_HEDLEY_LIKELY(current != char_traits<char_type>::eof()))
8420  {
8421  JSON_ASSERT(!token_string.empty());
8422  token_string.pop_back();
8423  }
8424  }
8425 
8427  void add(char_int_type c)
8428  {
8429  token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8430  }
8431 
8432  public:
8434  // value getters
8436 
8438  constexpr number_integer_t get_number_integer() const noexcept
8439  {
8440  return value_integer;
8441  }
8442 
8444  constexpr number_unsigned_t get_number_unsigned() const noexcept
8445  {
8446  return value_unsigned;
8447  }
8448 
8450  constexpr number_float_t get_number_float() const noexcept
8451  {
8452  return value_float;
8453  }
8454 
8456  string_t& get_string()
8457  {
8458  // translate decimal points from locale back to '.' (#4084)
8459  if (decimal_point_char != '.' && decimal_point_position != std::string::npos)
8460  {
8461  token_buffer[decimal_point_position] = '.';
8462  }
8463  return token_buffer;
8464  }
8465 
8467  // diagnostics
8469 
8471  constexpr position_t get_position() const noexcept
8472  {
8473  return position;
8474  }
8475 
8479  std::string get_token_string() const
8480  {
8481  // escape control characters
8482  std::string result;
8483  for (const auto c : token_string)
8484  {
8485  if (static_cast<unsigned char>(c) <= '\x1F')
8486  {
8487  // escape control characters
8488  std::array<char, 9> cs{{}};
8489  static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8490  result += cs.data();
8491  }
8492  else
8493  {
8494  // add character as is
8495  result.push_back(static_cast<std::string::value_type>(c));
8496  }
8497  }
8498 
8499  return result;
8500  }
8501 
8504  constexpr const char* get_error_message() const noexcept
8505  {
8506  return error_message;
8507  }
8508 
8510  // actual scanner
8512 
8517  bool skip_bom()
8518  {
8519  if (get() == 0xEF)
8520  {
8521  // check if we completely parse the BOM
8522  return get() == 0xBB && get() == 0xBF;
8523  }
8524 
8525  // the first character is not the beginning of the BOM; unget it to
8526  // process is later
8527  unget();
8528  return true;
8529  }
8530 
8532  {
8533  do
8534  {
8535  get();
8536  }
8537  while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8538  }
8539 
8541  {
8542  // initially, skip the BOM
8543  if (position.chars_read_total == 0 && !skip_bom())
8544  {
8545  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8546  return token_type::parse_error;
8547  }
8548 
8549  // read next character and ignore whitespace
8550  skip_whitespace();
8551 
8552  // ignore comments
8553  while (ignore_comments && current == '/')
8554  {
8555  if (!scan_comment())
8556  {
8557  return token_type::parse_error;
8558  }
8559 
8560  // skip following whitespace
8561  skip_whitespace();
8562  }
8563 
8564  switch (current)
8565  {
8566  // structural characters
8567  case '[':
8568  return token_type::begin_array;
8569  case ']':
8570  return token_type::end_array;
8571  case '{':
8572  return token_type::begin_object;
8573  case '}':
8574  return token_type::end_object;
8575  case ':':
8576  return token_type::name_separator;
8577  case ',':
8578  return token_type::value_separator;
8579 
8580  // literals
8581  case 't':
8582  {
8583  std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};
8584  return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8585  }
8586  case 'f':
8587  {
8588  std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};
8589  return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8590  }
8591  case 'n':
8592  {
8593  std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};
8594  return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8595  }
8596 
8597  // string
8598  case '\"':
8599  return scan_string();
8600 
8601  // number
8602  case '-':
8603  case '0':
8604  case '1':
8605  case '2':
8606  case '3':
8607  case '4':
8608  case '5':
8609  case '6':
8610  case '7':
8611  case '8':
8612  case '9':
8613  return scan_number();
8614 
8615  // end of input (the null byte is needed when parsing from
8616  // string literals)
8617  case '\0':
8619  return token_type::end_of_input;
8620 
8621  // error
8622  default:
8623  error_message = "invalid literal";
8624  return token_type::parse_error;
8625  }
8626  }
8627 
8628  private:
8630  InputAdapterType ia;
8631 
8633  const bool ignore_comments = false;
8634 
8636  char_int_type current = char_traits<char_type>::eof();
8637 
8639  bool next_unget = false;
8640 
8642  position_t position {};
8643 
8645  std::vector<char_type> token_string {};
8646 
8648  string_t token_buffer {};
8649 
8651  const char* error_message = "";
8652 
8653  // number values
8654  number_integer_t value_integer = 0;
8655  number_unsigned_t value_unsigned = 0;
8656  number_float_t value_float = 0;
8657 
8659  const char_int_type decimal_point_char = '.';
8661  std::size_t decimal_point_position = std::string::npos;
8662 };
8663 
8664 } // namespace detail
8666 
8667 // #include <nlohmann/detail/macro_scope.hpp>
8668 
8669 // #include <nlohmann/detail/string_concat.hpp>
8670 
8672 
8681 template<typename BasicJsonType>
8682 struct json_sax
8683 {
8684  using number_integer_t = typename BasicJsonType::number_integer_t;
8685  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8686  using number_float_t = typename BasicJsonType::number_float_t;
8687  using string_t = typename BasicJsonType::string_t;
8688  using binary_t = typename BasicJsonType::binary_t;
8689 
8694  virtual bool null() = 0;
8695 
8701  virtual bool boolean(bool val) = 0;
8702 
8708  virtual bool number_integer(number_integer_t val) = 0;
8709 
8715  virtual bool number_unsigned(number_unsigned_t val) = 0;
8716 
8723  virtual bool number_float(number_float_t val, const string_t& s) = 0;
8724 
8731  virtual bool string(string_t& val) = 0;
8732 
8739  virtual bool binary(binary_t& val) = 0;
8740 
8747  virtual bool start_object(std::size_t elements) = 0;
8748 
8755  virtual bool key(string_t& val) = 0;
8756 
8761  virtual bool end_object() = 0;
8762 
8769  virtual bool start_array(std::size_t elements) = 0;
8770 
8775  virtual bool end_array() = 0;
8776 
8784  virtual bool parse_error(std::size_t position,
8785  const std::string& last_token,
8786  const detail::exception& ex) = 0;
8787 
8788  json_sax() = default;
8789  json_sax(const json_sax&) = default;
8790  json_sax(json_sax&&) noexcept = default;
8791  json_sax& operator=(const json_sax&) = default;
8792  json_sax& operator=(json_sax&&) noexcept = default;
8793  virtual ~json_sax() = default;
8794 };
8795 
8796 namespace detail
8797 {
8798 constexpr std::size_t unknown_size()
8799 {
8800  return (std::numeric_limits<std::size_t>::max)();
8801 }
8802 
8816 template<typename BasicJsonType, typename InputAdapterType>
8818 {
8819  public:
8820  using number_integer_t = typename BasicJsonType::number_integer_t;
8821  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8822  using number_float_t = typename BasicJsonType::number_float_t;
8823  using string_t = typename BasicJsonType::string_t;
8824  using binary_t = typename BasicJsonType::binary_t;
8826 
8832  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true, lexer_t* lexer_ = nullptr)
8833  : root(r), allow_exceptions(allow_exceptions_), m_lexer_ref(lexer_)
8834  {}
8835 
8836  // make class move-only
8838  json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8840  json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8842 
8843  bool null()
8844  {
8845  handle_value(nullptr);
8846  return true;
8847  }
8848 
8849  bool boolean(bool val)
8850  {
8851  handle_value(val);
8852  return true;
8853  }
8854 
8856  {
8857  handle_value(val);
8858  return true;
8859  }
8860 
8862  {
8863  handle_value(val);
8864  return true;
8865  }
8866 
8867  bool number_float(number_float_t val, const string_t& /*unused*/)
8868  {
8869  handle_value(val);
8870  return true;
8871  }
8872 
8873  bool string(string_t& val)
8874  {
8875  handle_value(val);
8876  return true;
8877  }
8878 
8879  bool binary(binary_t& val)
8880  {
8881  handle_value(std::move(val));
8882  return true;
8883  }
8884 
8885  bool start_object(std::size_t len)
8886  {
8887  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
8888 
8889 #if JSON_DIAGNOSTIC_POSITIONS
8890  // Manually set the start position of the object here.
8891  // Ensure this is after the call to handle_value to ensure correct start position.
8892  if (m_lexer_ref)
8893  {
8894  // Lexer has read the first character of the object, so
8895  // subtract 1 from the position to get the correct start position.
8896  ref_stack.back()->start_position = m_lexer_ref->get_position() - 1;
8897  }
8898 #endif
8899 
8900  if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref_stack.back()->max_size()))
8901  {
8902  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
8903  }
8904 
8905  return true;
8906  }
8907 
8908  bool key(string_t& val)
8909  {
8910  JSON_ASSERT(!ref_stack.empty());
8911  JSON_ASSERT(ref_stack.back()->is_object());
8912 
8913  // add null at given key and store the reference for later
8914  object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val));
8915  return true;
8916  }
8917 
8918  bool end_object()
8919  {
8920  JSON_ASSERT(!ref_stack.empty());
8921  JSON_ASSERT(ref_stack.back()->is_object());
8922 
8923 #if JSON_DIAGNOSTIC_POSITIONS
8924  if (m_lexer_ref)
8925  {
8926  // Lexer's position is past the closing brace, so set that as the end position.
8927  ref_stack.back()->end_position = m_lexer_ref->get_position();
8928  }
8929 #endif
8930 
8931  ref_stack.back()->set_parents();
8932  ref_stack.pop_back();
8933  return true;
8934  }
8935 
8936  bool start_array(std::size_t len)
8937  {
8938  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
8939 
8940 #if JSON_DIAGNOSTIC_POSITIONS
8941  // Manually set the start position of the array here.
8942  // Ensure this is after the call to handle_value to ensure correct start position.
8943  if (m_lexer_ref)
8944  {
8945  ref_stack.back()->start_position = m_lexer_ref->get_position() - 1;
8946  }
8947 #endif
8948 
8949  if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref_stack.back()->max_size()))
8950  {
8951  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
8952  }
8953 
8954  return true;
8955  }
8956 
8957  bool end_array()
8958  {
8959  JSON_ASSERT(!ref_stack.empty());
8960  JSON_ASSERT(ref_stack.back()->is_array());
8961 
8962 #if JSON_DIAGNOSTIC_POSITIONS
8963  if (m_lexer_ref)
8964  {
8965  // Lexer's position is past the closing bracket, so set that as the end position.
8966  ref_stack.back()->end_position = m_lexer_ref->get_position();
8967  }
8968 #endif
8969 
8970  ref_stack.back()->set_parents();
8971  ref_stack.pop_back();
8972  return true;
8973  }
8974 
8975  template<class Exception>
8976  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
8977  const Exception& ex)
8978  {
8979  errored = true;
8980  static_cast<void>(ex);
8981  if (allow_exceptions)
8982  {
8983  JSON_THROW(ex);
8984  }
8985  return false;
8986  }
8987 
8988  constexpr bool is_errored() const
8989  {
8990  return errored;
8991  }
8992 
8993  private:
8994 
8995 #if JSON_DIAGNOSTIC_POSITIONS
8996  void handle_diagnostic_positions_for_json_value(BasicJsonType& v)
8997  {
8998  if (m_lexer_ref)
8999  {
9000  // Lexer has read past the current field value, so set the end position to the current position.
9001  // The start position will be set below based on the length of the string representation
9002  // of the value.
9003  v.end_position = m_lexer_ref->get_position();
9004 
9005  switch (v.type())
9006  {
9007  case value_t::boolean:
9008  {
9009  // 4 and 5 are the string length of "true" and "false"
9010  v.start_position = v.end_position - (v.m_data.m_value.boolean ? 4 : 5);
9011  break;
9012  }
9013 
9014  case value_t::null:
9015  {
9016  // 4 is the string length of "null"
9017  v.start_position = v.end_position - 4;
9018  break;
9019  }
9020 
9021  case value_t::string:
9022  {
9023  // include the length of the quotes, which is 2
9024  v.start_position = v.end_position - v.m_data.m_value.string->size() - 2;
9025  break;
9026  }
9027 
9028  // As we handle the start and end positions for values created during parsing,
9029  // we do not expect the following value type to be called. Regardless, set the positions
9030  // in case this is created manually or through a different constructor. Exclude from lcov
9031  // since the exact condition of this switch is esoteric.
9032  // LCOV_EXCL_START
9033  case value_t::discarded:
9034  {
9035  v.end_position = std::string::npos;
9036  v.start_position = v.end_position;
9037  break;
9038  }
9039  // LCOV_EXCL_STOP
9040  case value_t::binary:
9041  case value_t::number_integer:
9042  case value_t::number_unsigned:
9043  case value_t::number_float:
9044  {
9045  v.start_position = v.end_position - m_lexer_ref->get_string().size();
9046  break;
9047  }
9048  case value_t::object:
9049  case value_t::array:
9050  {
9051  // object and array are handled in start_object() and start_array() handlers
9052  // skip setting the values here.
9053  break;
9054  }
9055  default: // LCOV_EXCL_LINE
9056  // Handle all possible types discretely, default handler should never be reached.
9057  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert,-warnings-as-errors) LCOV_EXCL_LINE
9058  }
9059  }
9060  }
9061 #endif
9062 
9069  template<typename Value>
9071  BasicJsonType* handle_value(Value&& v)
9072  {
9073  if (ref_stack.empty())
9074  {
9075  root = BasicJsonType(std::forward<Value>(v));
9076 
9077 #if JSON_DIAGNOSTIC_POSITIONS
9078  handle_diagnostic_positions_for_json_value(root);
9079 #endif
9080 
9081  return &root;
9082  }
9083 
9084  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
9085 
9086  if (ref_stack.back()->is_array())
9087  {
9088  ref_stack.back()->m_data.m_value.array->emplace_back(std::forward<Value>(v));
9089 
9090 #if JSON_DIAGNOSTIC_POSITIONS
9091  handle_diagnostic_positions_for_json_value(ref_stack.back()->m_data.m_value.array->back());
9092 #endif
9093 
9094  return &(ref_stack.back()->m_data.m_value.array->back());
9095  }
9096 
9097  JSON_ASSERT(ref_stack.back()->is_object());
9098  JSON_ASSERT(object_element);
9099  *object_element = BasicJsonType(std::forward<Value>(v));
9100 
9101 #if JSON_DIAGNOSTIC_POSITIONS
9102  handle_diagnostic_positions_for_json_value(*object_element);
9103 #endif
9104 
9105  return object_element;
9106  }
9107 
9109  BasicJsonType& root;
9111  std::vector<BasicJsonType*> ref_stack {};
9113  BasicJsonType* object_element = nullptr;
9115  bool errored = false;
9117  const bool allow_exceptions = true;
9119  lexer_t* m_lexer_ref = nullptr;
9120 };
9121 
9122 template<typename BasicJsonType, typename InputAdapterType>
9124 {
9125  public:
9126  using number_integer_t = typename BasicJsonType::number_integer_t;
9127  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9128  using number_float_t = typename BasicJsonType::number_float_t;
9129  using string_t = typename BasicJsonType::string_t;
9130  using binary_t = typename BasicJsonType::binary_t;
9134 
9136  parser_callback_t cb,
9137  const bool allow_exceptions_ = true,
9138  lexer_t* lexer_ = nullptr)
9139  : root(r), callback(std::move(cb)), allow_exceptions(allow_exceptions_), m_lexer_ref(lexer_)
9140  {
9141  keep_stack.push_back(true);
9142  }
9143 
9144  // make class move-only
9146  json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9148  json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9150 
9151  bool null()
9152  {
9153  handle_value(nullptr);
9154  return true;
9155  }
9156 
9157  bool boolean(bool val)
9158  {
9159  handle_value(val);
9160  return true;
9161  }
9162 
9164  {
9165  handle_value(val);
9166  return true;
9167  }
9168 
9170  {
9171  handle_value(val);
9172  return true;
9173  }
9174 
9175  bool number_float(number_float_t val, const string_t& /*unused*/)
9176  {
9177  handle_value(val);
9178  return true;
9179  }
9180 
9181  bool string(string_t& val)
9182  {
9183  handle_value(val);
9184  return true;
9185  }
9186 
9187  bool binary(binary_t& val)
9188  {
9189  handle_value(std::move(val));
9190  return true;
9191  }
9192 
9193  bool start_object(std::size_t len)
9194  {
9195  // check callback for object start
9196  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
9197  keep_stack.push_back(keep);
9198 
9199  auto val = handle_value(BasicJsonType::value_t::object, true);
9200  ref_stack.push_back(val.second);
9201 
9202  if (ref_stack.back())
9203  {
9204 
9205 #if JSON_DIAGNOSTIC_POSITIONS
9206  // Manually set the start position of the object here.
9207  // Ensure this is after the call to handle_value to ensure correct start position.
9208  if (m_lexer_ref)
9209  {
9210  // Lexer has read the first character of the object, so
9211  // subtract 1 from the position to get the correct start position.
9212  ref_stack.back()->start_position = m_lexer_ref->get_position() - 1;
9213  }
9214 #endif
9215 
9216  // check object limit
9217  if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref_stack.back()->max_size()))
9218  {
9219  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
9220  }
9221  }
9222  return true;
9223  }
9224 
9225  bool key(string_t& val)
9226  {
9227  BasicJsonType k = BasicJsonType(val);
9228 
9229  // check callback for key
9230  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
9231  key_keep_stack.push_back(keep);
9232 
9233  // add discarded value at given key and store the reference for later
9234  if (keep && ref_stack.back())
9235  {
9236  object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val) = discarded);
9237  }
9238 
9239  return true;
9240  }
9241 
9242  bool end_object()
9243  {
9244  if (ref_stack.back())
9245  {
9246  if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
9247  {
9248  // discard object
9249  *ref_stack.back() = discarded;
9250 
9251 #if JSON_DIAGNOSTIC_POSITIONS
9252  // Set start/end positions for discarded object.
9253  handle_diagnostic_positions_for_json_value(*ref_stack.back());
9254 #endif
9255  }
9256  else
9257  {
9258 
9259 #if JSON_DIAGNOSTIC_POSITIONS
9260  if (m_lexer_ref)
9261  {
9262  // Lexer's position is past the closing brace, so set that as the end position.
9263  ref_stack.back()->end_position = m_lexer_ref->get_position();
9264  }
9265 #endif
9266 
9267  ref_stack.back()->set_parents();
9268  }
9269  }
9270 
9271  JSON_ASSERT(!ref_stack.empty());
9272  JSON_ASSERT(!keep_stack.empty());
9273  ref_stack.pop_back();
9274  keep_stack.pop_back();
9275 
9276  if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
9277  {
9278  // remove discarded value
9279  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
9280  {
9281  if (it->is_discarded())
9282  {
9283  ref_stack.back()->erase(it);
9284  break;
9285  }
9286  }
9287  }
9288 
9289  return true;
9290  }
9291 
9292  bool start_array(std::size_t len)
9293  {
9294  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
9295  keep_stack.push_back(keep);
9296 
9297  auto val = handle_value(BasicJsonType::value_t::array, true);
9298  ref_stack.push_back(val.second);
9299 
9300  if (ref_stack.back())
9301  {
9302 
9303 #if JSON_DIAGNOSTIC_POSITIONS
9304  // Manually set the start position of the array here.
9305  // Ensure this is after the call to handle_value to ensure correct start position.
9306  if (m_lexer_ref)
9307  {
9308  // Lexer has read the first character of the array, so
9309  // subtract 1 from the position to get the correct start position.
9310  ref_stack.back()->start_position = m_lexer_ref->get_position() - 1;
9311  }
9312 #endif
9313 
9314  // check array limit
9315  if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref_stack.back()->max_size()))
9316  {
9317  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
9318  }
9319  }
9320 
9321  return true;
9322  }
9323 
9324  bool end_array()
9325  {
9326  bool keep = true;
9327 
9328  if (ref_stack.back())
9329  {
9330  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
9331  if (keep)
9332  {
9333 
9334 #if JSON_DIAGNOSTIC_POSITIONS
9335  if (m_lexer_ref)
9336  {
9337  // Lexer's position is past the closing bracket, so set that as the end position.
9338  ref_stack.back()->end_position = m_lexer_ref->get_position();
9339  }
9340 #endif
9341 
9342  ref_stack.back()->set_parents();
9343  }
9344  else
9345  {
9346  // discard array
9347  *ref_stack.back() = discarded;
9348 
9349 #if JSON_DIAGNOSTIC_POSITIONS
9350  // Set start/end positions for discarded array.
9351  handle_diagnostic_positions_for_json_value(*ref_stack.back());
9352 #endif
9353  }
9354  }
9355 
9356  JSON_ASSERT(!ref_stack.empty());
9357  JSON_ASSERT(!keep_stack.empty());
9358  ref_stack.pop_back();
9359  keep_stack.pop_back();
9360 
9361  // remove discarded value
9362  if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
9363  {
9364  ref_stack.back()->m_data.m_value.array->pop_back();
9365  }
9366 
9367  return true;
9368  }
9369 
9370  template<class Exception>
9371  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
9372  const Exception& ex)
9373  {
9374  errored = true;
9375  static_cast<void>(ex);
9376  if (allow_exceptions)
9377  {
9378  JSON_THROW(ex);
9379  }
9380  return false;
9381  }
9382 
9383  constexpr bool is_errored() const
9384  {
9385  return errored;
9386  }
9387 
9388  private:
9389 
9390 #if JSON_DIAGNOSTIC_POSITIONS
9391  void handle_diagnostic_positions_for_json_value(BasicJsonType& v)
9392  {
9393  if (m_lexer_ref)
9394  {
9395  // Lexer has read past the current field value, so set the end position to the current position.
9396  // The start position will be set below based on the length of the string representation
9397  // of the value.
9398  v.end_position = m_lexer_ref->get_position();
9399 
9400  switch (v.type())
9401  {
9402  case value_t::boolean:
9403  {
9404  // 4 and 5 are the string length of "true" and "false"
9405  v.start_position = v.end_position - (v.m_data.m_value.boolean ? 4 : 5);
9406  break;
9407  }
9408 
9409  case value_t::null:
9410  {
9411  // 4 is the string length of "null"
9412  v.start_position = v.end_position - 4;
9413  break;
9414  }
9415 
9416  case value_t::string:
9417  {
9418  // include the length of the quotes, which is 2
9419  v.start_position = v.end_position - v.m_data.m_value.string->size() - 2;
9420  break;
9421  }
9422 
9423  case value_t::discarded:
9424  {
9425  v.end_position = std::string::npos;
9426  v.start_position = v.end_position;
9427  break;
9428  }
9429 
9430  case value_t::binary:
9431  case value_t::number_integer:
9432  case value_t::number_unsigned:
9433  case value_t::number_float:
9434  {
9435  v.start_position = v.end_position - m_lexer_ref->get_string().size();
9436  break;
9437  }
9438 
9439  case value_t::object:
9440  case value_t::array:
9441  {
9442  // object and array are handled in start_object() and start_array() handlers
9443  // skip setting the values here.
9444  break;
9445  }
9446  default: // LCOV_EXCL_LINE
9447  // Handle all possible types discretely, default handler should never be reached.
9448  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert,-warnings-as-errors) LCOV_EXCL_LINE
9449  }
9450  }
9451  }
9452 #endif
9453 
9469  template<typename Value>
9470  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
9471  {
9472  JSON_ASSERT(!keep_stack.empty());
9473 
9474  // do not handle this value if we know it would be added to a discarded
9475  // container
9476  if (!keep_stack.back())
9477  {
9478  return {false, nullptr};
9479  }
9480 
9481  // create value
9482  auto value = BasicJsonType(std::forward<Value>(v));
9483 
9484 #if JSON_DIAGNOSTIC_POSITIONS
9485  handle_diagnostic_positions_for_json_value(value);
9486 #endif
9487 
9488  // check callback
9489  const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
9490 
9491  // do not handle this value if we just learnt it shall be discarded
9492  if (!keep)
9493  {
9494  return {false, nullptr};
9495  }
9496 
9497  if (ref_stack.empty())
9498  {
9499  root = std::move(value);
9500  return {true, & root};
9501  }
9502 
9503  // skip this value if we already decided to skip the parent
9504  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
9505  if (!ref_stack.back())
9506  {
9507  return {false, nullptr};
9508  }
9509 
9510  // we now only expect arrays and objects
9511  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
9512 
9513  // array
9514  if (ref_stack.back()->is_array())
9515  {
9516  ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value));
9517  return {true, & (ref_stack.back()->m_data.m_value.array->back())};
9518  }
9519 
9520  // object
9521  JSON_ASSERT(ref_stack.back()->is_object());
9522  // check if we should store an element for the current key
9523  JSON_ASSERT(!key_keep_stack.empty());
9524  const bool store_element = key_keep_stack.back();
9525  key_keep_stack.pop_back();
9526 
9527  if (!store_element)
9528  {
9529  return {false, nullptr};
9530  }
9531 
9532  JSON_ASSERT(object_element);
9533  *object_element = std::move(value);
9534  return {true, object_element};
9535  }
9536 
9538  BasicJsonType& root;
9540  std::vector<BasicJsonType*> ref_stack {};
9542  std::vector<bool> keep_stack {}; // NOLINT(readability-redundant-member-init)
9544  std::vector<bool> key_keep_stack {}; // NOLINT(readability-redundant-member-init)
9546  BasicJsonType* object_element = nullptr;
9548  bool errored = false;
9550  const parser_callback_t callback = nullptr;
9552  const bool allow_exceptions = true;
9554  BasicJsonType discarded = BasicJsonType::value_t::discarded;
9556  lexer_t* m_lexer_ref = nullptr;
9557 };
9558 
9559 template<typename BasicJsonType>
9561 {
9562  public:
9563  using number_integer_t = typename BasicJsonType::number_integer_t;
9564  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9565  using number_float_t = typename BasicJsonType::number_float_t;
9566  using string_t = typename BasicJsonType::string_t;
9567  using binary_t = typename BasicJsonType::binary_t;
9568 
9569  bool null()
9570  {
9571  return true;
9572  }
9573 
9574  bool boolean(bool /*unused*/)
9575  {
9576  return true;
9577  }
9578 
9580  {
9581  return true;
9582  }
9583 
9585  {
9586  return true;
9587  }
9588 
9589  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
9590  {
9591  return true;
9592  }
9593 
9594  bool string(string_t& /*unused*/)
9595  {
9596  return true;
9597  }
9598 
9599  bool binary(binary_t& /*unused*/)
9600  {
9601  return true;
9602  }
9603 
9604  bool start_object(std::size_t /*unused*/ = detail::unknown_size())
9605  {
9606  return true;
9607  }
9608 
9609  bool key(string_t& /*unused*/)
9610  {
9611  return true;
9612  }
9613 
9614  bool end_object()
9615  {
9616  return true;
9617  }
9618 
9619  bool start_array(std::size_t /*unused*/ = detail::unknown_size())
9620  {
9621  return true;
9622  }
9623 
9624  bool end_array()
9625  {
9626  return true;
9627  }
9628 
9629  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
9630  {
9631  return false;
9632  }
9633 };
9634 
9635 } // namespace detail
9637 
9638 // #include <nlohmann/detail/input/lexer.hpp>
9639 
9640 // #include <nlohmann/detail/macro_scope.hpp>
9641 
9642 // #include <nlohmann/detail/meta/is_sax.hpp>
9643 // __ _____ _____ _____
9644 // __| | __| | | | JSON for Modern C++
9645 // | | |__ | | | | | | version 3.12.0
9646 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
9647 //
9648 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
9649 // SPDX-License-Identifier: MIT
9650 
9651 
9652 
9653 #include <cstdint> // size_t
9654 #include <utility> // declval
9655 #include <string> // string
9656 
9657 // #include <nlohmann/detail/abi_macros.hpp>
9658 
9659 // #include <nlohmann/detail/meta/detected.hpp>
9660 
9661 // #include <nlohmann/detail/meta/type_traits.hpp>
9662 
9663 
9665 namespace detail
9666 {
9667 
9668 template<typename T>
9669 using null_function_t = decltype(std::declval<T&>().null());
9670 
9671 template<typename T>
9673  decltype(std::declval<T&>().boolean(std::declval<bool>()));
9674 
9675 template<typename T, typename Integer>
9677  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
9678 
9679 template<typename T, typename Unsigned>
9681  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
9682 
9683 template<typename T, typename Float, typename String>
9684 using number_float_function_t = decltype(std::declval<T&>().number_float(
9685  std::declval<Float>(), std::declval<const String&>()));
9686 
9687 template<typename T, typename String>
9689  decltype(std::declval<T&>().string(std::declval<String&>()));
9690 
9691 template<typename T, typename Binary>
9693  decltype(std::declval<T&>().binary(std::declval<Binary&>()));
9694 
9695 template<typename T>
9697  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
9698 
9699 template<typename T, typename String>
9701  decltype(std::declval<T&>().key(std::declval<String&>()));
9702 
9703 template<typename T>
9704 using end_object_function_t = decltype(std::declval<T&>().end_object());
9705 
9706 template<typename T>
9708  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
9709 
9710 template<typename T>
9711 using end_array_function_t = decltype(std::declval<T&>().end_array());
9712 
9713 template<typename T, typename Exception>
9714 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
9715  std::declval<std::size_t>(), std::declval<const std::string&>(),
9716  std::declval<const Exception&>()));
9717 
9718 template<typename SAX, typename BasicJsonType>
9719 struct is_sax
9720 {
9721  private:
9723  "BasicJsonType must be of type basic_json<...>");
9724 
9725  using number_integer_t = typename BasicJsonType::number_integer_t;
9726  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9727  using number_float_t = typename BasicJsonType::number_float_t;
9728  using string_t = typename BasicJsonType::string_t;
9729  using binary_t = typename BasicJsonType::binary_t;
9730  using exception_t = typename BasicJsonType::exception;
9731 
9732  public:
9733  static constexpr bool value =
9747 };
9748 
9749 template<typename SAX, typename BasicJsonType>
9751 {
9752  private:
9754  "BasicJsonType must be of type basic_json<...>");
9755 
9756  using number_integer_t = typename BasicJsonType::number_integer_t;
9757  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9758  using number_float_t = typename BasicJsonType::number_float_t;
9759  using string_t = typename BasicJsonType::string_t;
9760  using binary_t = typename BasicJsonType::binary_t;
9761  using exception_t = typename BasicJsonType::exception;
9762 
9763  public:
9765  "Missing/invalid function: bool null()");
9767  "Missing/invalid function: bool boolean(bool)");
9769  "Missing/invalid function: bool boolean(bool)");
9770  static_assert(
9772  number_integer_t>::value,
9773  "Missing/invalid function: bool number_integer(number_integer_t)");
9774  static_assert(
9776  number_unsigned_t>::value,
9777  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
9778  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
9779  number_float_t, string_t>::value,
9780  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
9781  static_assert(
9783  "Missing/invalid function: bool string(string_t&)");
9784  static_assert(
9786  "Missing/invalid function: bool binary(binary_t&)");
9788  "Missing/invalid function: bool start_object(std::size_t)");
9790  "Missing/invalid function: bool key(string_t&)");
9792  "Missing/invalid function: bool end_object()");
9794  "Missing/invalid function: bool start_array(std::size_t)");
9796  "Missing/invalid function: bool end_array()");
9797  static_assert(
9799  "Missing/invalid function: bool parse_error(std::size_t, const "
9800  "std::string&, const exception&)");
9801 };
9802 
9803 } // namespace detail
9805 
9806 // #include <nlohmann/detail/meta/type_traits.hpp>
9807 
9808 // #include <nlohmann/detail/string_concat.hpp>
9809 
9810 // #include <nlohmann/detail/value_t.hpp>
9811 
9812 
9814 namespace detail
9815 {
9816 
9819 {
9820  error,
9821  ignore,
9822  store
9823 };
9824 
9832 static inline bool little_endianness(int num = 1) noexcept
9833 {
9834  return *reinterpret_cast<char*>(&num) == 1;
9835 }
9836 
9838 // binary reader //
9840 
9844 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType, InputAdapterType>>
9846 {
9847  using number_integer_t = typename BasicJsonType::number_integer_t;
9848  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9849  using number_float_t = typename BasicJsonType::number_float_t;
9850  using string_t = typename BasicJsonType::string_t;
9851  using binary_t = typename BasicJsonType::binary_t;
9852  using json_sax_t = SAX;
9853  using char_type = typename InputAdapterType::char_type;
9854  using char_int_type = typename char_traits<char_type>::int_type;
9855 
9856  public:
9862  explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
9863  {
9865  }
9866 
9867  // make class move-only
9868  binary_reader(const binary_reader&) = delete;
9869  binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9871  binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9872  ~binary_reader() = default;
9873 
9883  bool sax_parse(const input_format_t format,
9884  json_sax_t* sax_,
9885  const bool strict = true,
9886  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
9887  {
9888  sax = sax_;
9889  bool result = false;
9890 
9891  switch (format)
9892  {
9893  case input_format_t::bson:
9894  result = parse_bson_internal();
9895  break;
9896 
9897  case input_format_t::cbor:
9898  result = parse_cbor_internal(true, tag_handler);
9899  break;
9900 
9901  case input_format_t::msgpack:
9902  result = parse_msgpack_internal();
9903  break;
9904 
9905  case input_format_t::ubjson:
9906  case input_format_t::bjdata:
9907  result = parse_ubjson_internal();
9908  break;
9909 
9910  case input_format_t::json: // LCOV_EXCL_LINE
9911  default: // LCOV_EXCL_LINE
9912  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9913  }
9914 
9915  // strict mode: next byte must be EOF
9916  if (result && strict)
9917  {
9918  if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
9919  {
9920  get_ignore_noop();
9921  }
9922  else
9923  {
9924  get();
9925  }
9926 
9928  {
9929  return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
9930  exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
9931  }
9932  }
9933 
9934  return result;
9935  }
9936 
9937  private:
9939  // BSON //
9941 
9946  bool parse_bson_internal()
9947  {
9948  std::int32_t document_size{};
9949  get_number<std::int32_t, true>(input_format_t::bson, document_size);
9950 
9951  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size())))
9952  {
9953  return false;
9954  }
9955 
9956  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
9957  {
9958  return false;
9959  }
9960 
9961  return sax->end_object();
9962  }
9963 
9971  bool get_bson_cstr(string_t& result)
9972  {
9973  auto out = std::back_inserter(result);
9974  while (true)
9975  {
9976  get();
9977  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
9978  {
9979  return false;
9980  }
9981  if (current == 0x00)
9982  {
9983  return true;
9984  }
9985  *out++ = static_cast<typename string_t::value_type>(current);
9986  }
9987  }
9988 
10000  template<typename NumberType>
10001  bool get_bson_string(const NumberType len, string_t& result)
10002  {
10003  if (JSON_HEDLEY_UNLIKELY(len < 1))
10004  {
10005  auto last_token = get_token_string();
10006  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10007  exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
10008  }
10009 
10010  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != char_traits<char_type>::eof();
10011  }
10012 
10022  template<typename NumberType>
10023  bool get_bson_binary(const NumberType len, binary_t& result)
10024  {
10025  if (JSON_HEDLEY_UNLIKELY(len < 0))
10026  {
10027  auto last_token = get_token_string();
10028  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10029  exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
10030  }
10031 
10032  // All BSON binary values have a subtype
10033  std::uint8_t subtype{};
10034  get_number<std::uint8_t>(input_format_t::bson, subtype);
10035  result.set_subtype(subtype);
10036 
10037  return get_binary(input_format_t::bson, len, result);
10038  }
10039 
10050  bool parse_bson_element_internal(const char_int_type element_type,
10051  const std::size_t element_type_parse_position)
10052  {
10053  switch (element_type)
10054  {
10055  case 0x01: // double
10056  {
10057  double number{};
10058  return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10059  }
10060 
10061  case 0x02: // string
10062  {
10063  std::int32_t len{};
10064  string_t value;
10065  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
10066  }
10067 
10068  case 0x03: // object
10069  {
10070  return parse_bson_internal();
10071  }
10072 
10073  case 0x04: // array
10074  {
10075  return parse_bson_array();
10076  }
10077 
10078  case 0x05: // binary
10079  {
10080  std::int32_t len{};
10081  binary_t value;
10082  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
10083  }
10084 
10085  case 0x08: // boolean
10086  {
10087  return sax->boolean(get() != 0);
10088  }
10089 
10090  case 0x0A: // null
10091  {
10092  return sax->null();
10093  }
10094 
10095  case 0x10: // int32
10096  {
10097  std::int32_t value{};
10098  return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
10099  }
10100 
10101  case 0x12: // int64
10102  {
10103  std::int64_t value{};
10104  return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
10105  }
10106 
10107  case 0x11: // uint64
10108  {
10109  std::uint64_t value{};
10110  return get_number<std::uint64_t, true>(input_format_t::bson, value) && sax->number_unsigned(value);
10111  }
10112 
10113  default: // anything else not supported (yet)
10114  {
10115  std::array<char, 3> cr{{}};
10116  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10117  const std::string cr_str{cr.data()};
10118  return sax->parse_error(element_type_parse_position, cr_str,
10119  parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
10120  }
10121  }
10122  }
10123 
10136  bool parse_bson_element_list(const bool is_array)
10137  {
10138  string_t key;
10139 
10140  while (auto element_type = get())
10141  {
10142  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
10143  {
10144  return false;
10145  }
10146 
10147  const std::size_t element_type_parse_position = chars_read;
10148  if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
10149  {
10150  return false;
10151  }
10152 
10153  if (!is_array && !sax->key(key))
10154  {
10155  return false;
10156  }
10157 
10158  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
10159  {
10160  return false;
10161  }
10162 
10163  // get_bson_cstr only appends
10164  key.clear();
10165  }
10166 
10167  return true;
10168  }
10169 
10174  bool parse_bson_array()
10175  {
10176  std::int32_t document_size{};
10177  get_number<std::int32_t, true>(input_format_t::bson, document_size);
10178 
10179  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size())))
10180  {
10181  return false;
10182  }
10183 
10184  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
10185  {
10186  return false;
10187  }
10188 
10189  return sax->end_array();
10190  }
10191 
10193  // CBOR //
10195 
10204  bool parse_cbor_internal(const bool get_char,
10205  const cbor_tag_handler_t tag_handler)
10206  {
10207  switch (get_char ? get() : current)
10208  {
10209  // EOF
10210  case char_traits<char_type>::eof():
10211  return unexpect_eof(input_format_t::cbor, "value");
10212 
10213  // Integer 0x00..0x17 (0..23)
10214  case 0x00:
10215  case 0x01:
10216  case 0x02:
10217  case 0x03:
10218  case 0x04:
10219  case 0x05:
10220  case 0x06:
10221  case 0x07:
10222  case 0x08:
10223  case 0x09:
10224  case 0x0A:
10225  case 0x0B:
10226  case 0x0C:
10227  case 0x0D:
10228  case 0x0E:
10229  case 0x0F:
10230  case 0x10:
10231  case 0x11:
10232  case 0x12:
10233  case 0x13:
10234  case 0x14:
10235  case 0x15:
10236  case 0x16:
10237  case 0x17:
10238  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
10239 
10240  case 0x18: // Unsigned integer (one-byte uint8_t follows)
10241  {
10242  std::uint8_t number{};
10243  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
10244  }
10245 
10246  case 0x19: // Unsigned integer (two-byte uint16_t follows)
10247  {
10248  std::uint16_t number{};
10249  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
10250  }
10251 
10252  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
10253  {
10254  std::uint32_t number{};
10255  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
10256  }
10257 
10258  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
10259  {
10260  std::uint64_t number{};
10261  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
10262  }
10263 
10264  // Negative integer -1-0x00..-1-0x17 (-1..-24)
10265  case 0x20:
10266  case 0x21:
10267  case 0x22:
10268  case 0x23:
10269  case 0x24:
10270  case 0x25:
10271  case 0x26:
10272  case 0x27:
10273  case 0x28:
10274  case 0x29:
10275  case 0x2A:
10276  case 0x2B:
10277  case 0x2C:
10278  case 0x2D:
10279  case 0x2E:
10280  case 0x2F:
10281  case 0x30:
10282  case 0x31:
10283  case 0x32:
10284  case 0x33:
10285  case 0x34:
10286  case 0x35:
10287  case 0x36:
10288  case 0x37:
10289  return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
10290 
10291  case 0x38: // Negative integer (one-byte uint8_t follows)
10292  {
10293  std::uint8_t number{};
10294  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
10295  }
10296 
10297  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
10298  {
10299  std::uint16_t number{};
10300  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
10301  }
10302 
10303  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
10304  {
10305  std::uint32_t number{};
10306  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
10307  }
10308 
10309  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
10310  {
10311  std::uint64_t number{};
10312  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
10313  - static_cast<number_integer_t>(number));
10314  }
10315 
10316  // Binary data (0x00..0x17 bytes follow)
10317  case 0x40:
10318  case 0x41:
10319  case 0x42:
10320  case 0x43:
10321  case 0x44:
10322  case 0x45:
10323  case 0x46:
10324  case 0x47:
10325  case 0x48:
10326  case 0x49:
10327  case 0x4A:
10328  case 0x4B:
10329  case 0x4C:
10330  case 0x4D:
10331  case 0x4E:
10332  case 0x4F:
10333  case 0x50:
10334  case 0x51:
10335  case 0x52:
10336  case 0x53:
10337  case 0x54:
10338  case 0x55:
10339  case 0x56:
10340  case 0x57:
10341  case 0x58: // Binary data (one-byte uint8_t for n follows)
10342  case 0x59: // Binary data (two-byte uint16_t for n follow)
10343  case 0x5A: // Binary data (four-byte uint32_t for n follow)
10344  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
10345  case 0x5F: // Binary data (indefinite length)
10346  {
10347  binary_t b;
10348  return get_cbor_binary(b) && sax->binary(b);
10349  }
10350 
10351  // UTF-8 string (0x00..0x17 bytes follow)
10352  case 0x60:
10353  case 0x61:
10354  case 0x62:
10355  case 0x63:
10356  case 0x64:
10357  case 0x65:
10358  case 0x66:
10359  case 0x67:
10360  case 0x68:
10361  case 0x69:
10362  case 0x6A:
10363  case 0x6B:
10364  case 0x6C:
10365  case 0x6D:
10366  case 0x6E:
10367  case 0x6F:
10368  case 0x70:
10369  case 0x71:
10370  case 0x72:
10371  case 0x73:
10372  case 0x74:
10373  case 0x75:
10374  case 0x76:
10375  case 0x77:
10376  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
10377  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
10378  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
10379  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
10380  case 0x7F: // UTF-8 string (indefinite length)
10381  {
10382  string_t s;
10383  return get_cbor_string(s) && sax->string(s);
10384  }
10385 
10386  // array (0x00..0x17 data items follow)
10387  case 0x80:
10388  case 0x81:
10389  case 0x82:
10390  case 0x83:
10391  case 0x84:
10392  case 0x85:
10393  case 0x86:
10394  case 0x87:
10395  case 0x88:
10396  case 0x89:
10397  case 0x8A:
10398  case 0x8B:
10399  case 0x8C:
10400  case 0x8D:
10401  case 0x8E:
10402  case 0x8F:
10403  case 0x90:
10404  case 0x91:
10405  case 0x92:
10406  case 0x93:
10407  case 0x94:
10408  case 0x95:
10409  case 0x96:
10410  case 0x97:
10411  return get_cbor_array(
10412  conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
10413 
10414  case 0x98: // array (one-byte uint8_t for n follows)
10415  {
10416  std::uint8_t len{};
10417  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
10418  }
10419 
10420  case 0x99: // array (two-byte uint16_t for n follow)
10421  {
10422  std::uint16_t len{};
10423  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
10424  }
10425 
10426  case 0x9A: // array (four-byte uint32_t for n follow)
10427  {
10428  std::uint32_t len{};
10429  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
10430  }
10431 
10432  case 0x9B: // array (eight-byte uint64_t for n follow)
10433  {
10434  std::uint64_t len{};
10435  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
10436  }
10437 
10438  case 0x9F: // array (indefinite length)
10439  return get_cbor_array(detail::unknown_size(), tag_handler);
10440 
10441  // map (0x00..0x17 pairs of data items follow)
10442  case 0xA0:
10443  case 0xA1:
10444  case 0xA2:
10445  case 0xA3:
10446  case 0xA4:
10447  case 0xA5:
10448  case 0xA6:
10449  case 0xA7:
10450  case 0xA8:
10451  case 0xA9:
10452  case 0xAA:
10453  case 0xAB:
10454  case 0xAC:
10455  case 0xAD:
10456  case 0xAE:
10457  case 0xAF:
10458  case 0xB0:
10459  case 0xB1:
10460  case 0xB2:
10461  case 0xB3:
10462  case 0xB4:
10463  case 0xB5:
10464  case 0xB6:
10465  case 0xB7:
10466  return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
10467 
10468  case 0xB8: // map (one-byte uint8_t for n follows)
10469  {
10470  std::uint8_t len{};
10471  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
10472  }
10473 
10474  case 0xB9: // map (two-byte uint16_t for n follow)
10475  {
10476  std::uint16_t len{};
10477  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
10478  }
10479 
10480  case 0xBA: // map (four-byte uint32_t for n follow)
10481  {
10482  std::uint32_t len{};
10483  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
10484  }
10485 
10486  case 0xBB: // map (eight-byte uint64_t for n follow)
10487  {
10488  std::uint64_t len{};
10489  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
10490  }
10491 
10492  case 0xBF: // map (indefinite length)
10493  return get_cbor_object(detail::unknown_size(), tag_handler);
10494 
10495  case 0xC6: // tagged item
10496  case 0xC7:
10497  case 0xC8:
10498  case 0xC9:
10499  case 0xCA:
10500  case 0xCB:
10501  case 0xCC:
10502  case 0xCD:
10503  case 0xCE:
10504  case 0xCF:
10505  case 0xD0:
10506  case 0xD1:
10507  case 0xD2:
10508  case 0xD3:
10509  case 0xD4:
10510  case 0xD8: // tagged item (1 bytes follow)
10511  case 0xD9: // tagged item (2 bytes follow)
10512  case 0xDA: // tagged item (4 bytes follow)
10513  case 0xDB: // tagged item (8 bytes follow)
10514  {
10515  switch (tag_handler)
10516  {
10517  case cbor_tag_handler_t::error:
10518  {
10519  auto last_token = get_token_string();
10520  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10521  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
10522  }
10523 
10524  case cbor_tag_handler_t::ignore:
10525  {
10526  // ignore binary subtype
10527  switch (current)
10528  {
10529  case 0xD8:
10530  {
10531  std::uint8_t subtype_to_ignore{};
10532  get_number(input_format_t::cbor, subtype_to_ignore);
10533  break;
10534  }
10535  case 0xD9:
10536  {
10537  std::uint16_t subtype_to_ignore{};
10538  get_number(input_format_t::cbor, subtype_to_ignore);
10539  break;
10540  }
10541  case 0xDA:
10542  {
10543  std::uint32_t subtype_to_ignore{};
10544  get_number(input_format_t::cbor, subtype_to_ignore);
10545  break;
10546  }
10547  case 0xDB:
10548  {
10549  std::uint64_t subtype_to_ignore{};
10550  get_number(input_format_t::cbor, subtype_to_ignore);
10551  break;
10552  }
10553  default:
10554  break;
10555  }
10556  return parse_cbor_internal(true, tag_handler);
10557  }
10558 
10559  case cbor_tag_handler_t::store:
10560  {
10561  binary_t b;
10562  // use binary subtype and store in binary container
10563  switch (current)
10564  {
10565  case 0xD8:
10566  {
10567  std::uint8_t subtype{};
10568  get_number(input_format_t::cbor, subtype);
10569  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
10570  break;
10571  }
10572  case 0xD9:
10573  {
10574  std::uint16_t subtype{};
10575  get_number(input_format_t::cbor, subtype);
10576  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
10577  break;
10578  }
10579  case 0xDA:
10580  {
10581  std::uint32_t subtype{};
10582  get_number(input_format_t::cbor, subtype);
10583  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
10584  break;
10585  }
10586  case 0xDB:
10587  {
10588  std::uint64_t subtype{};
10589  get_number(input_format_t::cbor, subtype);
10590  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
10591  break;
10592  }
10593  default:
10594  return parse_cbor_internal(true, tag_handler);
10595  }
10596  get();
10597  return get_cbor_binary(b) && sax->binary(b);
10598  }
10599 
10600  default: // LCOV_EXCL_LINE
10601  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10602  return false; // LCOV_EXCL_LINE
10603  }
10604  }
10605 
10606  case 0xF4: // false
10607  return sax->boolean(false);
10608 
10609  case 0xF5: // true
10610  return sax->boolean(true);
10611 
10612  case 0xF6: // null
10613  return sax->null();
10614 
10615  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
10616  {
10617  const auto byte1_raw = get();
10618  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
10619  {
10620  return false;
10621  }
10622  const auto byte2_raw = get();
10623  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
10624  {
10625  return false;
10626  }
10627 
10628  const auto byte1 = static_cast<unsigned char>(byte1_raw);
10629  const auto byte2 = static_cast<unsigned char>(byte2_raw);
10630 
10631  // code from RFC 7049, Appendix D, Figure 3:
10632  // As half-precision floating-point numbers were only added
10633  // to IEEE 754 in 2008, today's programming platforms often
10634  // still only have limited support for them. It is very
10635  // easy to include at least decoding support for them even
10636  // without such support. An example of a small decoder for
10637  // half-precision floating-point numbers in the C language
10638  // is shown in Fig. 3.
10639  const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
10640  const double val = [&half]
10641  {
10642  const int exp = (half >> 10u) & 0x1Fu;
10643  const unsigned int mant = half & 0x3FFu;
10644  JSON_ASSERT(0 <= exp&& exp <= 32);
10645  JSON_ASSERT(mant <= 1024);
10646  switch (exp)
10647  {
10648  case 0:
10649  return std::ldexp(mant, -24);
10650  case 31:
10651  return (mant == 0)
10652  ? std::numeric_limits<double>::infinity()
10653  : std::numeric_limits<double>::quiet_NaN();
10654  default:
10655  return std::ldexp(mant + 1024, exp - 25);
10656  }
10657  }();
10658  return sax->number_float((half & 0x8000u) != 0
10659  ? static_cast<number_float_t>(-val)
10660  : static_cast<number_float_t>(val), "");
10661  }
10662 
10663  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
10664  {
10665  float number{};
10666  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
10667  }
10668 
10669  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
10670  {
10671  double number{};
10672  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
10673  }
10674 
10675  default: // anything else (0xFF is handled inside the other types)
10676  {
10677  auto last_token = get_token_string();
10678  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10679  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
10680  }
10681  }
10682  }
10683 
10695  bool get_cbor_string(string_t& result)
10696  {
10697  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
10698  {
10699  return false;
10700  }
10701 
10702  switch (current)
10703  {
10704  // UTF-8 string (0x00..0x17 bytes follow)
10705  case 0x60:
10706  case 0x61:
10707  case 0x62:
10708  case 0x63:
10709  case 0x64:
10710  case 0x65:
10711  case 0x66:
10712  case 0x67:
10713  case 0x68:
10714  case 0x69:
10715  case 0x6A:
10716  case 0x6B:
10717  case 0x6C:
10718  case 0x6D:
10719  case 0x6E:
10720  case 0x6F:
10721  case 0x70:
10722  case 0x71:
10723  case 0x72:
10724  case 0x73:
10725  case 0x74:
10726  case 0x75:
10727  case 0x76:
10728  case 0x77:
10729  {
10730  return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10731  }
10732 
10733  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
10734  {
10735  std::uint8_t len{};
10736  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10737  }
10738 
10739  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
10740  {
10741  std::uint16_t len{};
10742  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10743  }
10744 
10745  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
10746  {
10747  std::uint32_t len{};
10748  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10749  }
10750 
10751  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
10752  {
10753  std::uint64_t len{};
10754  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10755  }
10756 
10757  case 0x7F: // UTF-8 string (indefinite length)
10758  {
10759  while (get() != 0xFF)
10760  {
10761  string_t chunk;
10762  if (!get_cbor_string(chunk))
10763  {
10764  return false;
10765  }
10766  result.append(chunk);
10767  }
10768  return true;
10769  }
10770 
10771  default:
10772  {
10773  auto last_token = get_token_string();
10774  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10775  exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
10776  }
10777  }
10778  }
10779 
10791  bool get_cbor_binary(binary_t& result)
10792  {
10793  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
10794  {
10795  return false;
10796  }
10797 
10798  switch (current)
10799  {
10800  // Binary data (0x00..0x17 bytes follow)
10801  case 0x40:
10802  case 0x41:
10803  case 0x42:
10804  case 0x43:
10805  case 0x44:
10806  case 0x45:
10807  case 0x46:
10808  case 0x47:
10809  case 0x48:
10810  case 0x49:
10811  case 0x4A:
10812  case 0x4B:
10813  case 0x4C:
10814  case 0x4D:
10815  case 0x4E:
10816  case 0x4F:
10817  case 0x50:
10818  case 0x51:
10819  case 0x52:
10820  case 0x53:
10821  case 0x54:
10822  case 0x55:
10823  case 0x56:
10824  case 0x57:
10825  {
10826  return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10827  }
10828 
10829  case 0x58: // Binary data (one-byte uint8_t for n follows)
10830  {
10831  std::uint8_t len{};
10832  return get_number(input_format_t::cbor, len) &&
10833  get_binary(input_format_t::cbor, len, result);
10834  }
10835 
10836  case 0x59: // Binary data (two-byte uint16_t for n follow)
10837  {
10838  std::uint16_t len{};
10839  return get_number(input_format_t::cbor, len) &&
10840  get_binary(input_format_t::cbor, len, result);
10841  }
10842 
10843  case 0x5A: // Binary data (four-byte uint32_t for n follow)
10844  {
10845  std::uint32_t len{};
10846  return get_number(input_format_t::cbor, len) &&
10847  get_binary(input_format_t::cbor, len, result);
10848  }
10849 
10850  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
10851  {
10852  std::uint64_t len{};
10853  return get_number(input_format_t::cbor, len) &&
10854  get_binary(input_format_t::cbor, len, result);
10855  }
10856 
10857  case 0x5F: // Binary data (indefinite length)
10858  {
10859  while (get() != 0xFF)
10860  {
10861  binary_t chunk;
10862  if (!get_cbor_binary(chunk))
10863  {
10864  return false;
10865  }
10866  result.insert(result.end(), chunk.begin(), chunk.end());
10867  }
10868  return true;
10869  }
10870 
10871  default:
10872  {
10873  auto last_token = get_token_string();
10874  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10875  exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr));
10876  }
10877  }
10878  }
10879 
10886  bool get_cbor_array(const std::size_t len,
10887  const cbor_tag_handler_t tag_handler)
10888  {
10889  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10890  {
10891  return false;
10892  }
10893 
10894  if (len != detail::unknown_size())
10895  {
10896  for (std::size_t i = 0; i < len; ++i)
10897  {
10898  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10899  {
10900  return false;
10901  }
10902  }
10903  }
10904  else
10905  {
10906  while (get() != 0xFF)
10907  {
10908  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
10909  {
10910  return false;
10911  }
10912  }
10913  }
10914 
10915  return sax->end_array();
10916  }
10917 
10924  bool get_cbor_object(const std::size_t len,
10925  const cbor_tag_handler_t tag_handler)
10926  {
10927  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10928  {
10929  return false;
10930  }
10931 
10932  if (len != 0)
10933  {
10934  string_t key;
10935  if (len != detail::unknown_size())
10936  {
10937  for (std::size_t i = 0; i < len; ++i)
10938  {
10939  get();
10940  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10941  {
10942  return false;
10943  }
10944 
10945  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10946  {
10947  return false;
10948  }
10949  key.clear();
10950  }
10951  }
10952  else
10953  {
10954  while (get() != 0xFF)
10955  {
10956  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10957  {
10958  return false;
10959  }
10960 
10961  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10962  {
10963  return false;
10964  }
10965  key.clear();
10966  }
10967  }
10968  }
10969 
10970  return sax->end_object();
10971  }
10972 
10974  // MsgPack //
10976 
10980  bool parse_msgpack_internal()
10981  {
10982  switch (get())
10983  {
10984  // EOF
10985  case char_traits<char_type>::eof():
10986  return unexpect_eof(input_format_t::msgpack, "value");
10987 
10988  // positive fixint
10989  case 0x00:
10990  case 0x01:
10991  case 0x02:
10992  case 0x03:
10993  case 0x04:
10994  case 0x05:
10995  case 0x06:
10996  case 0x07:
10997  case 0x08:
10998  case 0x09:
10999  case 0x0A:
11000  case 0x0B:
11001  case 0x0C:
11002  case 0x0D:
11003  case 0x0E:
11004  case 0x0F:
11005  case 0x10:
11006  case 0x11:
11007  case 0x12:
11008  case 0x13:
11009  case 0x14:
11010  case 0x15:
11011  case 0x16:
11012  case 0x17:
11013  case 0x18:
11014  case 0x19:
11015  case 0x1A:
11016  case 0x1B:
11017  case 0x1C:
11018  case 0x1D:
11019  case 0x1E:
11020  case 0x1F:
11021  case 0x20:
11022  case 0x21:
11023  case 0x22:
11024  case 0x23:
11025  case 0x24:
11026  case 0x25:
11027  case 0x26:
11028  case 0x27:
11029  case 0x28:
11030  case 0x29:
11031  case 0x2A:
11032  case 0x2B:
11033  case 0x2C:
11034  case 0x2D:
11035  case 0x2E:
11036  case 0x2F:
11037  case 0x30:
11038  case 0x31:
11039  case 0x32:
11040  case 0x33:
11041  case 0x34:
11042  case 0x35:
11043  case 0x36:
11044  case 0x37:
11045  case 0x38:
11046  case 0x39:
11047  case 0x3A:
11048  case 0x3B:
11049  case 0x3C:
11050  case 0x3D:
11051  case 0x3E:
11052  case 0x3F:
11053  case 0x40:
11054  case 0x41:
11055  case 0x42:
11056  case 0x43:
11057  case 0x44:
11058  case 0x45:
11059  case 0x46:
11060  case 0x47:
11061  case 0x48:
11062  case 0x49:
11063  case 0x4A:
11064  case 0x4B:
11065  case 0x4C:
11066  case 0x4D:
11067  case 0x4E:
11068  case 0x4F:
11069  case 0x50:
11070  case 0x51:
11071  case 0x52:
11072  case 0x53:
11073  case 0x54:
11074  case 0x55:
11075  case 0x56:
11076  case 0x57:
11077  case 0x58:
11078  case 0x59:
11079  case 0x5A:
11080  case 0x5B:
11081  case 0x5C:
11082  case 0x5D:
11083  case 0x5E:
11084  case 0x5F:
11085  case 0x60:
11086  case 0x61:
11087  case 0x62:
11088  case 0x63:
11089  case 0x64:
11090  case 0x65:
11091  case 0x66:
11092  case 0x67:
11093  case 0x68:
11094  case 0x69:
11095  case 0x6A:
11096  case 0x6B:
11097  case 0x6C:
11098  case 0x6D:
11099  case 0x6E:
11100  case 0x6F:
11101  case 0x70:
11102  case 0x71:
11103  case 0x72:
11104  case 0x73:
11105  case 0x74:
11106  case 0x75:
11107  case 0x76:
11108  case 0x77:
11109  case 0x78:
11110  case 0x79:
11111  case 0x7A:
11112  case 0x7B:
11113  case 0x7C:
11114  case 0x7D:
11115  case 0x7E:
11116  case 0x7F:
11117  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
11118 
11119  // fixmap
11120  case 0x80:
11121  case 0x81:
11122  case 0x82:
11123  case 0x83:
11124  case 0x84:
11125  case 0x85:
11126  case 0x86:
11127  case 0x87:
11128  case 0x88:
11129  case 0x89:
11130  case 0x8A:
11131  case 0x8B:
11132  case 0x8C:
11133  case 0x8D:
11134  case 0x8E:
11135  case 0x8F:
11136  return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
11137 
11138  // fixarray
11139  case 0x90:
11140  case 0x91:
11141  case 0x92:
11142  case 0x93:
11143  case 0x94:
11144  case 0x95:
11145  case 0x96:
11146  case 0x97:
11147  case 0x98:
11148  case 0x99:
11149  case 0x9A:
11150  case 0x9B:
11151  case 0x9C:
11152  case 0x9D:
11153  case 0x9E:
11154  case 0x9F:
11155  return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
11156 
11157  // fixstr
11158  case 0xA0:
11159  case 0xA1:
11160  case 0xA2:
11161  case 0xA3:
11162  case 0xA4:
11163  case 0xA5:
11164  case 0xA6:
11165  case 0xA7:
11166  case 0xA8:
11167  case 0xA9:
11168  case 0xAA:
11169  case 0xAB:
11170  case 0xAC:
11171  case 0xAD:
11172  case 0xAE:
11173  case 0xAF:
11174  case 0xB0:
11175  case 0xB1:
11176  case 0xB2:
11177  case 0xB3:
11178  case 0xB4:
11179  case 0xB5:
11180  case 0xB6:
11181  case 0xB7:
11182  case 0xB8:
11183  case 0xB9:
11184  case 0xBA:
11185  case 0xBB:
11186  case 0xBC:
11187  case 0xBD:
11188  case 0xBE:
11189  case 0xBF:
11190  case 0xD9: // str 8
11191  case 0xDA: // str 16
11192  case 0xDB: // str 32
11193  {
11194  string_t s;
11195  return get_msgpack_string(s) && sax->string(s);
11196  }
11197 
11198  case 0xC0: // nil
11199  return sax->null();
11200 
11201  case 0xC2: // false
11202  return sax->boolean(false);
11203 
11204  case 0xC3: // true
11205  return sax->boolean(true);
11206 
11207  case 0xC4: // bin 8
11208  case 0xC5: // bin 16
11209  case 0xC6: // bin 32
11210  case 0xC7: // ext 8
11211  case 0xC8: // ext 16
11212  case 0xC9: // ext 32
11213  case 0xD4: // fixext 1
11214  case 0xD5: // fixext 2
11215  case 0xD6: // fixext 4
11216  case 0xD7: // fixext 8
11217  case 0xD8: // fixext 16
11218  {
11219  binary_t b;
11220  return get_msgpack_binary(b) && sax->binary(b);
11221  }
11222 
11223  case 0xCA: // float 32
11224  {
11225  float number{};
11226  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
11227  }
11228 
11229  case 0xCB: // float 64
11230  {
11231  double number{};
11232  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
11233  }
11234 
11235  case 0xCC: // uint 8
11236  {
11237  std::uint8_t number{};
11238  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
11239  }
11240 
11241  case 0xCD: // uint 16
11242  {
11243  std::uint16_t number{};
11244  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
11245  }
11246 
11247  case 0xCE: // uint 32
11248  {
11249  std::uint32_t number{};
11250  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
11251  }
11252 
11253  case 0xCF: // uint 64
11254  {
11255  std::uint64_t number{};
11256  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
11257  }
11258 
11259  case 0xD0: // int 8
11260  {
11261  std::int8_t number{};
11262  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
11263  }
11264 
11265  case 0xD1: // int 16
11266  {
11267  std::int16_t number{};
11268  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
11269  }
11270 
11271  case 0xD2: // int 32
11272  {
11273  std::int32_t number{};
11274  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
11275  }
11276 
11277  case 0xD3: // int 64
11278  {
11279  std::int64_t number{};
11280  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
11281  }
11282 
11283  case 0xDC: // array 16
11284  {
11285  std::uint16_t len{};
11286  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
11287  }
11288 
11289  case 0xDD: // array 32
11290  {
11291  std::uint32_t len{};
11292  return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len));
11293  }
11294 
11295  case 0xDE: // map 16
11296  {
11297  std::uint16_t len{};
11298  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
11299  }
11300 
11301  case 0xDF: // map 32
11302  {
11303  std::uint32_t len{};
11304  return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len));
11305  }
11306 
11307  // negative fixint
11308  case 0xE0:
11309  case 0xE1:
11310  case 0xE2:
11311  case 0xE3:
11312  case 0xE4:
11313  case 0xE5:
11314  case 0xE6:
11315  case 0xE7:
11316  case 0xE8:
11317  case 0xE9:
11318  case 0xEA:
11319  case 0xEB:
11320  case 0xEC:
11321  case 0xED:
11322  case 0xEE:
11323  case 0xEF:
11324  case 0xF0:
11325  case 0xF1:
11326  case 0xF2:
11327  case 0xF3:
11328  case 0xF4:
11329  case 0xF5:
11330  case 0xF6:
11331  case 0xF7:
11332  case 0xF8:
11333  case 0xF9:
11334  case 0xFA:
11335  case 0xFB:
11336  case 0xFC:
11337  case 0xFD:
11338  case 0xFE:
11339  case 0xFF:
11340  return sax->number_integer(static_cast<std::int8_t>(current));
11341 
11342  default: // anything else
11343  {
11344  auto last_token = get_token_string();
11345  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11346  exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
11347  }
11348  }
11349  }
11350 
11361  bool get_msgpack_string(string_t& result)
11362  {
11363  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
11364  {
11365  return false;
11366  }
11367 
11368  switch (current)
11369  {
11370  // fixstr
11371  case 0xA0:
11372  case 0xA1:
11373  case 0xA2:
11374  case 0xA3:
11375  case 0xA4:
11376  case 0xA5:
11377  case 0xA6:
11378  case 0xA7:
11379  case 0xA8:
11380  case 0xA9:
11381  case 0xAA:
11382  case 0xAB:
11383  case 0xAC:
11384  case 0xAD:
11385  case 0xAE:
11386  case 0xAF:
11387  case 0xB0:
11388  case 0xB1:
11389  case 0xB2:
11390  case 0xB3:
11391  case 0xB4:
11392  case 0xB5:
11393  case 0xB6:
11394  case 0xB7:
11395  case 0xB8:
11396  case 0xB9:
11397  case 0xBA:
11398  case 0xBB:
11399  case 0xBC:
11400  case 0xBD:
11401  case 0xBE:
11402  case 0xBF:
11403  {
11404  return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
11405  }
11406 
11407  case 0xD9: // str 8
11408  {
11409  std::uint8_t len{};
11410  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
11411  }
11412 
11413  case 0xDA: // str 16
11414  {
11415  std::uint16_t len{};
11416  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
11417  }
11418 
11419  case 0xDB: // str 32
11420  {
11421  std::uint32_t len{};
11422  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
11423  }
11424 
11425  default:
11426  {
11427  auto last_token = get_token_string();
11428  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
11429  exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
11430  }
11431  }
11432  }
11433 
11444  bool get_msgpack_binary(binary_t& result)
11445  {
11446  // helper function to set the subtype
11447  auto assign_and_return_true = [&result](std::int8_t subtype)
11448  {
11449  result.set_subtype(static_cast<std::uint8_t>(subtype));
11450  return true;
11451  };
11452 
11453  switch (current)
11454  {
11455  case 0xC4: // bin 8
11456  {
11457  std::uint8_t len{};
11458  return get_number(input_format_t::msgpack, len) &&
11459  get_binary(input_format_t::msgpack, len, result);
11460  }
11461 
11462  case 0xC5: // bin 16
11463  {
11464  std::uint16_t len{};
11465  return get_number(input_format_t::msgpack, len) &&
11466  get_binary(input_format_t::msgpack, len, result);
11467  }
11468 
11469  case 0xC6: // bin 32
11470  {
11471  std::uint32_t len{};
11472  return get_number(input_format_t::msgpack, len) &&
11473  get_binary(input_format_t::msgpack, len, result);
11474  }
11475 
11476  case 0xC7: // ext 8
11477  {
11478  std::uint8_t len{};
11479  std::int8_t subtype{};
11480  return get_number(input_format_t::msgpack, len) &&
11481  get_number(input_format_t::msgpack, subtype) &&
11482  get_binary(input_format_t::msgpack, len, result) &&
11483  assign_and_return_true(subtype);
11484  }
11485 
11486  case 0xC8: // ext 16
11487  {
11488  std::uint16_t len{};
11489  std::int8_t subtype{};
11490  return get_number(input_format_t::msgpack, len) &&
11491  get_number(input_format_t::msgpack, subtype) &&
11492  get_binary(input_format_t::msgpack, len, result) &&
11493  assign_and_return_true(subtype);
11494  }
11495 
11496  case 0xC9: // ext 32
11497  {
11498  std::uint32_t len{};
11499  std::int8_t subtype{};
11500  return get_number(input_format_t::msgpack, len) &&
11501  get_number(input_format_t::msgpack, subtype) &&
11502  get_binary(input_format_t::msgpack, len, result) &&
11503  assign_and_return_true(subtype);
11504  }
11505 
11506  case 0xD4: // fixext 1
11507  {
11508  std::int8_t subtype{};
11509  return get_number(input_format_t::msgpack, subtype) &&
11510  get_binary(input_format_t::msgpack, 1, result) &&
11511  assign_and_return_true(subtype);
11512  }
11513 
11514  case 0xD5: // fixext 2
11515  {
11516  std::int8_t subtype{};
11517  return get_number(input_format_t::msgpack, subtype) &&
11518  get_binary(input_format_t::msgpack, 2, result) &&
11519  assign_and_return_true(subtype);
11520  }
11521 
11522  case 0xD6: // fixext 4
11523  {
11524  std::int8_t subtype{};
11525  return get_number(input_format_t::msgpack, subtype) &&
11526  get_binary(input_format_t::msgpack, 4, result) &&
11527  assign_and_return_true(subtype);
11528  }
11529 
11530  case 0xD7: // fixext 8
11531  {
11532  std::int8_t subtype{};
11533  return get_number(input_format_t::msgpack, subtype) &&
11534  get_binary(input_format_t::msgpack, 8, result) &&
11535  assign_and_return_true(subtype);
11536  }
11537 
11538  case 0xD8: // fixext 16
11539  {
11540  std::int8_t subtype{};
11541  return get_number(input_format_t::msgpack, subtype) &&
11542  get_binary(input_format_t::msgpack, 16, result) &&
11543  assign_and_return_true(subtype);
11544  }
11545 
11546  default: // LCOV_EXCL_LINE
11547  return false; // LCOV_EXCL_LINE
11548  }
11549  }
11550 
11555  bool get_msgpack_array(const std::size_t len)
11556  {
11557  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
11558  {
11559  return false;
11560  }
11561 
11562  for (std::size_t i = 0; i < len; ++i)
11563  {
11564  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
11565  {
11566  return false;
11567  }
11568  }
11569 
11570  return sax->end_array();
11571  }
11572 
11577  bool get_msgpack_object(const std::size_t len)
11578  {
11579  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
11580  {
11581  return false;
11582  }
11583 
11584  string_t key;
11585  for (std::size_t i = 0; i < len; ++i)
11586  {
11587  get();
11588  if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
11589  {
11590  return false;
11591  }
11592 
11593  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
11594  {
11595  return false;
11596  }
11597  key.clear();
11598  }
11599 
11600  return sax->end_object();
11601  }
11602 
11604  // UBJSON //
11606 
11614  bool parse_ubjson_internal(const bool get_char = true)
11615  {
11616  return get_ubjson_value(get_char ? get_ignore_noop() : current);
11617  }
11618 
11633  bool get_ubjson_string(string_t& result, const bool get_char = true)
11634  {
11635  if (get_char)
11636  {
11637  get(); // TODO(niels): may we ignore N here?
11638  }
11639 
11640  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
11641  {
11642  return false;
11643  }
11644 
11645  switch (current)
11646  {
11647  case 'U':
11648  {
11649  std::uint8_t len{};
11650  return get_number(input_format, len) && get_string(input_format, len, result);
11651  }
11652 
11653  case 'i':
11654  {
11655  std::int8_t len{};
11656  return get_number(input_format, len) && get_string(input_format, len, result);
11657  }
11658 
11659  case 'I':
11660  {
11661  std::int16_t len{};
11662  return get_number(input_format, len) && get_string(input_format, len, result);
11663  }
11664 
11665  case 'l':
11666  {
11667  std::int32_t len{};
11668  return get_number(input_format, len) && get_string(input_format, len, result);
11669  }
11670 
11671  case 'L':
11672  {
11673  std::int64_t len{};
11674  return get_number(input_format, len) && get_string(input_format, len, result);
11675  }
11676 
11677  case 'u':
11678  {
11679  if (input_format != input_format_t::bjdata)
11680  {
11681  break;
11682  }
11683  std::uint16_t len{};
11684  return get_number(input_format, len) && get_string(input_format, len, result);
11685  }
11686 
11687  case 'm':
11688  {
11689  if (input_format != input_format_t::bjdata)
11690  {
11691  break;
11692  }
11693  std::uint32_t len{};
11694  return get_number(input_format, len) && get_string(input_format, len, result);
11695  }
11696 
11697  case 'M':
11698  {
11699  if (input_format != input_format_t::bjdata)
11700  {
11701  break;
11702  }
11703  std::uint64_t len{};
11704  return get_number(input_format, len) && get_string(input_format, len, result);
11705  }
11706 
11707  default:
11708  break;
11709  }
11710  auto last_token = get_token_string();
11711  std::string message;
11712 
11713  if (input_format != input_format_t::bjdata)
11714  {
11715  message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
11716  }
11717  else
11718  {
11719  message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
11720  }
11721  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
11722  }
11723 
11728  bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
11729  {
11730  std::pair<std::size_t, char_int_type> size_and_type;
11731  size_t dimlen = 0;
11732  bool no_ndarray = true;
11733 
11734  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))
11735  {
11736  return false;
11737  }
11738 
11739  if (size_and_type.first != npos)
11740  {
11741  if (size_and_type.second != 0)
11742  {
11743  if (size_and_type.second != 'N')
11744  {
11745  for (std::size_t i = 0; i < size_and_type.first; ++i)
11746  {
11747  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))
11748  {
11749  return false;
11750  }
11751  dim.push_back(dimlen);
11752  }
11753  }
11754  }
11755  else
11756  {
11757  for (std::size_t i = 0; i < size_and_type.first; ++i)
11758  {
11759  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))
11760  {
11761  return false;
11762  }
11763  dim.push_back(dimlen);
11764  }
11765  }
11766  }
11767  else
11768  {
11769  while (current != ']')
11770  {
11771  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))
11772  {
11773  return false;
11774  }
11775  dim.push_back(dimlen);
11776  get_ignore_noop();
11777  }
11778  }
11779  return true;
11780  }
11781 
11793  bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)
11794  {
11795  if (prefix == 0)
11796  {
11797  prefix = get_ignore_noop();
11798  }
11799 
11800  switch (prefix)
11801  {
11802  case 'U':
11803  {
11804  std::uint8_t number{};
11805  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11806  {
11807  return false;
11808  }
11809  result = static_cast<std::size_t>(number);
11810  return true;
11811  }
11812 
11813  case 'i':
11814  {
11815  std::int8_t number{};
11816  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11817  {
11818  return false;
11819  }
11820  if (number < 0)
11821  {
11822  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11823  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11824  }
11825  result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
11826  return true;
11827  }
11828 
11829  case 'I':
11830  {
11831  std::int16_t number{};
11832  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11833  {
11834  return false;
11835  }
11836  if (number < 0)
11837  {
11838  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11839  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11840  }
11841  result = static_cast<std::size_t>(number);
11842  return true;
11843  }
11844 
11845  case 'l':
11846  {
11847  std::int32_t number{};
11848  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11849  {
11850  return false;
11851  }
11852  if (number < 0)
11853  {
11854  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11855  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11856  }
11857  result = static_cast<std::size_t>(number);
11858  return true;
11859  }
11860 
11861  case 'L':
11862  {
11863  std::int64_t number{};
11864  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11865  {
11866  return false;
11867  }
11868  if (number < 0)
11869  {
11870  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11871  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11872  }
11873  if (!value_in_range_of<std::size_t>(number))
11874  {
11875  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11876  exception_message(input_format, "integer value overflow", "size"), nullptr));
11877  }
11878  result = static_cast<std::size_t>(number);
11879  return true;
11880  }
11881 
11882  case 'u':
11883  {
11884  if (input_format != input_format_t::bjdata)
11885  {
11886  break;
11887  }
11888  std::uint16_t number{};
11889  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11890  {
11891  return false;
11892  }
11893  result = static_cast<std::size_t>(number);
11894  return true;
11895  }
11896 
11897  case 'm':
11898  {
11899  if (input_format != input_format_t::bjdata)
11900  {
11901  break;
11902  }
11903  std::uint32_t number{};
11904  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11905  {
11906  return false;
11907  }
11908  result = conditional_static_cast<std::size_t>(number);
11909  return true;
11910  }
11911 
11912  case 'M':
11913  {
11914  if (input_format != input_format_t::bjdata)
11915  {
11916  break;
11917  }
11918  std::uint64_t number{};
11919  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11920  {
11921  return false;
11922  }
11923  if (!value_in_range_of<std::size_t>(number))
11924  {
11925  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11926  exception_message(input_format, "integer value overflow", "size"), nullptr));
11927  }
11928  result = detail::conditional_static_cast<std::size_t>(number);
11929  return true;
11930  }
11931 
11932  case '[':
11933  {
11934  if (input_format != input_format_t::bjdata)
11935  {
11936  break;
11937  }
11938  if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
11939  {
11940  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimensional vector is not allowed", "size"), nullptr));
11941  }
11942  std::vector<size_t> dim;
11943  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
11944  {
11945  return false;
11946  }
11947  if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
11948  {
11949  result = dim.at(dim.size() - 1);
11950  return true;
11951  }
11952  if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
11953  {
11954  for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container
11955  {
11956  if ( i == 0 )
11957  {
11958  result = 0;
11959  return true;
11960  }
11961  }
11962 
11963  string_t key = "_ArraySize_";
11964  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
11965  {
11966  return false;
11967  }
11968  result = 1;
11969  for (auto i : dim)
11970  {
11971  result *= i;
11972  if (result == 0 || result == npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be npos as it is used to initialize size in get_ubjson_size_type()
11973  {
11974  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr));
11975  }
11976  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
11977  {
11978  return false;
11979  }
11980  }
11981  is_ndarray = true;
11982  return sax->end_array();
11983  }
11984  result = 0;
11985  return true;
11986  }
11987 
11988  default:
11989  break;
11990  }
11991  auto last_token = get_token_string();
11992  std::string message;
11993 
11994  if (input_format != input_format_t::bjdata)
11995  {
11996  message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
11997  }
11998  else
11999  {
12000  message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
12001  }
12002  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
12003  }
12004 
12016  bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)
12017  {
12018  result.first = npos; // size
12019  result.second = 0; // type
12020  bool is_ndarray = false;
12021 
12022  get_ignore_noop();
12023 
12024  if (current == '$')
12025  {
12026  result.second = get(); // must not ignore 'N', because 'N' maybe the type
12027  if (input_format == input_format_t::bjdata
12028  && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))
12029  {
12030  auto last_token = get_token_string();
12031  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
12032  exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
12033  }
12034 
12035  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
12036  {
12037  return false;
12038  }
12039 
12040  get_ignore_noop();
12041  if (JSON_HEDLEY_UNLIKELY(current != '#'))
12042  {
12043  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
12044  {
12045  return false;
12046  }
12047  auto last_token = get_token_string();
12048  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
12049  exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
12050  }
12051 
12052  const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
12053  if (input_format == input_format_t::bjdata && is_ndarray)
12054  {
12055  if (inside_ndarray)
12056  {
12057  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
12058  exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
12059  }
12060  result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
12061  }
12062  return is_error;
12063  }
12064 
12065  if (current == '#')
12066  {
12067  const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
12068  if (input_format == input_format_t::bjdata && is_ndarray)
12069  {
12070  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
12071  exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
12072  }
12073  return is_error;
12074  }
12075 
12076  return true;
12077  }
12078 
12083  bool get_ubjson_value(const char_int_type prefix)
12084  {
12085  switch (prefix)
12086  {
12087  case char_traits<char_type>::eof(): // EOF
12088  return unexpect_eof(input_format, "value");
12089 
12090  case 'T': // true
12091  return sax->boolean(true);
12092  case 'F': // false
12093  return sax->boolean(false);
12094 
12095  case 'Z': // null
12096  return sax->null();
12097 
12098  case 'B': // byte
12099  {
12100  if (input_format != input_format_t::bjdata)
12101  {
12102  break;
12103  }
12104  std::uint8_t number{};
12105  return get_number(input_format, number) && sax->number_unsigned(number);
12106  }
12107 
12108  case 'U':
12109  {
12110  std::uint8_t number{};
12111  return get_number(input_format, number) && sax->number_unsigned(number);
12112  }
12113 
12114  case 'i':
12115  {
12116  std::int8_t number{};
12117  return get_number(input_format, number) && sax->number_integer(number);
12118  }
12119 
12120  case 'I':
12121  {
12122  std::int16_t number{};
12123  return get_number(input_format, number) && sax->number_integer(number);
12124  }
12125 
12126  case 'l':
12127  {
12128  std::int32_t number{};
12129  return get_number(input_format, number) && sax->number_integer(number);
12130  }
12131 
12132  case 'L':
12133  {
12134  std::int64_t number{};
12135  return get_number(input_format, number) && sax->number_integer(number);
12136  }
12137 
12138  case 'u':
12139  {
12140  if (input_format != input_format_t::bjdata)
12141  {
12142  break;
12143  }
12144  std::uint16_t number{};
12145  return get_number(input_format, number) && sax->number_unsigned(number);
12146  }
12147 
12148  case 'm':
12149  {
12150  if (input_format != input_format_t::bjdata)
12151  {
12152  break;
12153  }
12154  std::uint32_t number{};
12155  return get_number(input_format, number) && sax->number_unsigned(number);
12156  }
12157 
12158  case 'M':
12159  {
12160  if (input_format != input_format_t::bjdata)
12161  {
12162  break;
12163  }
12164  std::uint64_t number{};
12165  return get_number(input_format, number) && sax->number_unsigned(number);
12166  }
12167 
12168  case 'h':
12169  {
12170  if (input_format != input_format_t::bjdata)
12171  {
12172  break;
12173  }
12174  const auto byte1_raw = get();
12175  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
12176  {
12177  return false;
12178  }
12179  const auto byte2_raw = get();
12180  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
12181  {
12182  return false;
12183  }
12184 
12185  const auto byte1 = static_cast<unsigned char>(byte1_raw);
12186  const auto byte2 = static_cast<unsigned char>(byte2_raw);
12187 
12188  // code from RFC 7049, Appendix D, Figure 3:
12189  // As half-precision floating-point numbers were only added
12190  // to IEEE 754 in 2008, today's programming platforms often
12191  // still only have limited support for them. It is very
12192  // easy to include at least decoding support for them even
12193  // without such support. An example of a small decoder for
12194  // half-precision floating-point numbers in the C language
12195  // is shown in Fig. 3.
12196  const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
12197  const double val = [&half]
12198  {
12199  const int exp = (half >> 10u) & 0x1Fu;
12200  const unsigned int mant = half & 0x3FFu;
12201  JSON_ASSERT(0 <= exp&& exp <= 32);
12202  JSON_ASSERT(mant <= 1024);
12203  switch (exp)
12204  {
12205  case 0:
12206  return std::ldexp(mant, -24);
12207  case 31:
12208  return (mant == 0)
12209  ? std::numeric_limits<double>::infinity()
12210  : std::numeric_limits<double>::quiet_NaN();
12211  default:
12212  return std::ldexp(mant + 1024, exp - 25);
12213  }
12214  }();
12215  return sax->number_float((half & 0x8000u) != 0
12216  ? static_cast<number_float_t>(-val)
12217  : static_cast<number_float_t>(val), "");
12218  }
12219 
12220  case 'd':
12221  {
12222  float number{};
12223  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
12224  }
12225 
12226  case 'D':
12227  {
12228  double number{};
12229  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
12230  }
12231 
12232  case 'H':
12233  {
12234  return get_ubjson_high_precision_number();
12235  }
12236 
12237  case 'C': // char
12238  {
12239  get();
12240  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
12241  {
12242  return false;
12243  }
12244  if (JSON_HEDLEY_UNLIKELY(current > 127))
12245  {
12246  auto last_token = get_token_string();
12247  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
12248  exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
12249  }
12250  string_t s(1, static_cast<typename string_t::value_type>(current));
12251  return sax->string(s);
12252  }
12253 
12254  case 'S': // string
12255  {
12256  string_t s;
12257  return get_ubjson_string(s) && sax->string(s);
12258  }
12259 
12260  case '[': // array
12261  return get_ubjson_array();
12262 
12263  case '{': // object
12264  return get_ubjson_object();
12265 
12266  default: // anything else
12267  break;
12268  }
12269  auto last_token = get_token_string();
12270  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr));
12271  }
12272 
12276  bool get_ubjson_array()
12277  {
12278  std::pair<std::size_t, char_int_type> size_and_type;
12279  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
12280  {
12281  return false;
12282  }
12283 
12284  // if bit-8 of size_and_type.second is set to 1, encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata):
12285  // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
12286 
12287  if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
12288  {
12289  size_and_type.second &= ~(static_cast<char_int_type>(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker
12290  auto it = std::lower_bound(bjd_types_map.begin(), bjd_types_map.end(), size_and_type.second, [](const bjd_type & p, char_int_type t)
12291  {
12292  return p.first < t;
12293  });
12294  string_t key = "_ArrayType_";
12295  if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))
12296  {
12297  auto last_token = get_token_string();
12298  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
12299  exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
12300  }
12301 
12302  string_t type = it->second; // sax->string() takes a reference
12303  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type)))
12304  {
12305  return false;
12306  }
12307 
12308  if (size_and_type.second == 'C' || size_and_type.second == 'B')
12309  {
12310  size_and_type.second = 'U';
12311  }
12312 
12313  key = "_ArrayData_";
12314  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) ))
12315  {
12316  return false;
12317  }
12318 
12319  for (std::size_t i = 0; i < size_and_type.first; ++i)
12320  {
12321  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
12322  {
12323  return false;
12324  }
12325  }
12326 
12327  return (sax->end_array() && sax->end_object());
12328  }
12329 
12330  // If BJData type marker is 'B' decode as binary
12331  if (input_format == input_format_t::bjdata && size_and_type.first != npos && size_and_type.second == 'B')
12332  {
12333  binary_t result;
12334  return get_binary(input_format, size_and_type.first, result) && sax->binary(result);
12335  }
12336 
12337  if (size_and_type.first != npos)
12338  {
12339  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
12340  {
12341  return false;
12342  }
12343 
12344  if (size_and_type.second != 0)
12345  {
12346  if (size_and_type.second != 'N')
12347  {
12348  for (std::size_t i = 0; i < size_and_type.first; ++i)
12349  {
12350  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
12351  {
12352  return false;
12353  }
12354  }
12355  }
12356  }
12357  else
12358  {
12359  for (std::size_t i = 0; i < size_and_type.first; ++i)
12360  {
12361  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
12362  {
12363  return false;
12364  }
12365  }
12366  }
12367  }
12368  else
12369  {
12370  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size())))
12371  {
12372  return false;
12373  }
12374 
12375  while (current != ']')
12376  {
12377  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
12378  {
12379  return false;
12380  }
12381  get_ignore_noop();
12382  }
12383  }
12384 
12385  return sax->end_array();
12386  }
12387 
12391  bool get_ubjson_object()
12392  {
12393  std::pair<std::size_t, char_int_type> size_and_type;
12394  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
12395  {
12396  return false;
12397  }
12398 
12399  // do not accept ND-array size in objects in BJData
12400  if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
12401  {
12402  auto last_token = get_token_string();
12403  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
12404  exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
12405  }
12406 
12407  string_t key;
12408  if (size_and_type.first != npos)
12409  {
12410  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
12411  {
12412  return false;
12413  }
12414 
12415  if (size_and_type.second != 0)
12416  {
12417  for (std::size_t i = 0; i < size_and_type.first; ++i)
12418  {
12419  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
12420  {
12421  return false;
12422  }
12423  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
12424  {
12425  return false;
12426  }
12427  key.clear();
12428  }
12429  }
12430  else
12431  {
12432  for (std::size_t i = 0; i < size_and_type.first; ++i)
12433  {
12434  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
12435  {
12436  return false;
12437  }
12438  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
12439  {
12440  return false;
12441  }
12442  key.clear();
12443  }
12444  }
12445  }
12446  else
12447  {
12448  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size())))
12449  {
12450  return false;
12451  }
12452 
12453  while (current != '}')
12454  {
12455  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
12456  {
12457  return false;
12458  }
12459  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
12460  {
12461  return false;
12462  }
12463  get_ignore_noop();
12464  key.clear();
12465  }
12466  }
12467 
12468  return sax->end_object();
12469  }
12470 
12471  // Note, no reader for UBJSON binary types is implemented because they do
12472  // not exist
12473 
12474  bool get_ubjson_high_precision_number()
12475  {
12476  // get size of following number string
12477  std::size_t size{};
12478  bool no_ndarray = true;
12479  auto res = get_ubjson_size_value(size, no_ndarray);
12480  if (JSON_HEDLEY_UNLIKELY(!res))
12481  {
12482  return res;
12483  }
12484 
12485  // get number string
12486  std::vector<char> number_vector;
12487  for (std::size_t i = 0; i < size; ++i)
12488  {
12489  get();
12490  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
12491  {
12492  return false;
12493  }
12494  number_vector.push_back(static_cast<char>(current));
12495  }
12496 
12497  // parse number string
12498  using ia_type = decltype(detail::input_adapter(number_vector));
12499  auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
12500  const auto result_number = number_lexer.scan();
12501  const auto number_string = number_lexer.get_token_string();
12502  const auto result_remainder = number_lexer.scan();
12503 
12504  using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
12505 
12506  if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
12507  {
12508  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
12509  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
12510  }
12511 
12512  switch (result_number)
12513  {
12514  case token_type::value_integer:
12515  return sax->number_integer(number_lexer.get_number_integer());
12516  case token_type::value_unsigned:
12517  return sax->number_unsigned(number_lexer.get_number_unsigned());
12518  case token_type::value_float:
12519  return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
12520  case token_type::uninitialized:
12521  case token_type::literal_true:
12522  case token_type::literal_false:
12523  case token_type::literal_null:
12524  case token_type::value_string:
12525  case token_type::begin_array:
12526  case token_type::begin_object:
12527  case token_type::end_array:
12528  case token_type::end_object:
12529  case token_type::name_separator:
12530  case token_type::value_separator:
12531  case token_type::parse_error:
12532  case token_type::end_of_input:
12533  case token_type::literal_or_value:
12534  default:
12535  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
12536  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
12537  }
12538  }
12539 
12541  // Utility functions //
12543 
12553  char_int_type get()
12554  {
12555  ++chars_read;
12556  return current = ia.get_character();
12557  }
12558 
12567  template<class T>
12568  bool get_to(T& dest, const input_format_t format, const char* context)
12569  {
12570  auto new_chars_read = ia.get_elements(&dest);
12571  chars_read += new_chars_read;
12572  if (JSON_HEDLEY_UNLIKELY(new_chars_read < sizeof(T)))
12573  {
12574  // in case of failure, advance position by 1 to report failing location
12575  ++chars_read;
12576  sax->parse_error(chars_read, "<end of file>", parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
12577  return false;
12578  }
12579  return true;
12580  }
12581 
12585  char_int_type get_ignore_noop()
12586  {
12587  do
12588  {
12589  get();
12590  }
12591  while (current == 'N');
12592 
12593  return current;
12594  }
12595 
12596  template<class NumberType>
12597  static void byte_swap(NumberType& number)
12598  {
12599  constexpr std::size_t sz = sizeof(number);
12600 #ifdef __cpp_lib_byteswap
12601  if constexpr (sz == 1)
12602  {
12603  return;
12604  }
12605  if constexpr(std::is_integral_v<NumberType>)
12606  {
12607  number = std::byteswap(number);
12608  return;
12609  }
12610 #endif
12611  auto* ptr = reinterpret_cast<std::uint8_t*>(&number);
12612  for (std::size_t i = 0; i < sz / 2; ++i)
12613  {
12614  std::swap(ptr[i], ptr[sz - i - 1]);
12615  }
12616  }
12617 
12618  /*
12619  @brief read a number from the input
12620 
12621  @tparam NumberType the type of the number
12622  @param[in] format the current format (for diagnostics)
12623  @param[out] result number of type @a NumberType
12624 
12625  @return whether conversion completed
12626 
12627  @note This function needs to respect the system's endianness, because
12628  bytes in CBOR, MessagePack, and UBJSON are stored in network order
12629  (big endian) and therefore need reordering on little endian systems.
12630  On the other hand, BSON and BJData use little endian and should reorder
12631  on big endian systems.
12632  */
12633  template<typename NumberType, bool InputIsLittleEndian = false>
12634  bool get_number(const input_format_t format, NumberType& result)
12635  {
12636  // read in the original format
12637 
12638  if (JSON_HEDLEY_UNLIKELY(!get_to(result, format, "number")))
12639  {
12640  return false;
12641  }
12642  if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
12643  {
12644  byte_swap(result);
12645  }
12646  return true;
12647  }
12648 
12663  template<typename NumberType>
12664  bool get_string(const input_format_t format,
12665  const NumberType len,
12666  string_t& result)
12667  {
12668  bool success = true;
12669  for (NumberType i = 0; i < len; i++)
12670  {
12671  get();
12672  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
12673  {
12674  success = false;
12675  break;
12676  }
12677  result.push_back(static_cast<typename string_t::value_type>(current));
12678  }
12679  return success;
12680  }
12681 
12696  template<typename NumberType>
12697  bool get_binary(const input_format_t format,
12698  const NumberType len,
12699  binary_t& result)
12700  {
12701  bool success = true;
12702  for (NumberType i = 0; i < len; i++)
12703  {
12704  get();
12705  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
12706  {
12707  success = false;
12708  break;
12709  }
12710  result.push_back(static_cast<std::uint8_t>(current));
12711  }
12712  return success;
12713  }
12714 
12721  bool unexpect_eof(const input_format_t format, const char* context) const
12722  {
12723  if (JSON_HEDLEY_UNLIKELY(current == char_traits<char_type>::eof()))
12724  {
12725  return sax->parse_error(chars_read, "<end of file>",
12726  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
12727  }
12728  return true;
12729  }
12730 
12734  std::string get_token_string() const
12735  {
12736  std::array<char, 3> cr{{}};
12737  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
12738  return std::string{cr.data()};
12739  }
12740 
12747  std::string exception_message(const input_format_t format,
12748  const std::string& detail,
12749  const std::string& context) const
12750  {
12751  std::string error_msg = "syntax error while parsing ";
12752 
12753  switch (format)
12754  {
12755  case input_format_t::cbor:
12756  error_msg += "CBOR";
12757  break;
12758 
12759  case input_format_t::msgpack:
12760  error_msg += "MessagePack";
12761  break;
12762 
12763  case input_format_t::ubjson:
12764  error_msg += "UBJSON";
12765  break;
12766 
12767  case input_format_t::bson:
12768  error_msg += "BSON";
12769  break;
12770 
12771  case input_format_t::bjdata:
12772  error_msg += "BJData";
12773  break;
12774 
12775  case input_format_t::json: // LCOV_EXCL_LINE
12776  default: // LCOV_EXCL_LINE
12777  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
12778  }
12779 
12780  return concat(error_msg, ' ', context, ": ", detail);
12781  }
12782 
12783  private:
12784  static JSON_INLINE_VARIABLE constexpr std::size_t npos = detail::unknown_size();
12785 
12787  InputAdapterType ia;
12788 
12790  char_int_type current = char_traits<char_type>::eof();
12791 
12793  std::size_t chars_read = 0;
12794 
12796  const bool is_little_endian = little_endianness();
12797 
12799  const input_format_t input_format = input_format_t::json;
12800 
12802  json_sax_t* sax = nullptr;
12803 
12804  // excluded markers in bjdata optimized type
12805 #define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \
12806  make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')
12807 
12808 #define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \
12809  make_array<bjd_type>( \
12810  bjd_type{'B', "byte"}, \
12811  bjd_type{'C', "char"}, \
12812  bjd_type{'D', "double"}, \
12813  bjd_type{'I', "int16"}, \
12814  bjd_type{'L', "int64"}, \
12815  bjd_type{'M', "uint64"}, \
12816  bjd_type{'U', "uint8"}, \
12817  bjd_type{'d', "single"}, \
12818  bjd_type{'i', "int8"}, \
12819  bjd_type{'l', "int32"}, \
12820  bjd_type{'m', "uint32"}, \
12821  bjd_type{'u', "uint16"})
12822 
12824  // lookup tables
12825  // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12826  const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers =
12828 
12829  using bjd_type = std::pair<char_int_type, string_t>;
12830  // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12831  const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map =
12833 
12834 #undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
12835 #undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
12836 };
12837 
12838 #ifndef JSON_HAS_CPP_17
12839  template<typename BasicJsonType, typename InputAdapterType, typename SAX>
12840  constexpr std::size_t binary_reader<BasicJsonType, InputAdapterType, SAX>::npos;
12841 #endif
12842 
12843 } // namespace detail
12845 
12846 // #include <nlohmann/detail/input/input_adapters.hpp>
12847 
12848 // #include <nlohmann/detail/input/lexer.hpp>
12849 
12850 // #include <nlohmann/detail/input/parser.hpp>
12851 // __ _____ _____ _____
12852 // __| | __| | | | JSON for Modern C++
12853 // | | |__ | | | | | | version 3.12.0
12854 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
12855 //
12856 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
12857 // SPDX-License-Identifier: MIT
12858 
12859 
12860 
12861 #include <cmath> // isfinite
12862 #include <cstdint> // uint8_t
12863 #include <functional> // function
12864 #include <string> // string
12865 #include <utility> // move
12866 #include <vector> // vector
12867 
12868 // #include <nlohmann/detail/exceptions.hpp>
12869 
12870 // #include <nlohmann/detail/input/input_adapters.hpp>
12871 
12872 // #include <nlohmann/detail/input/json_sax.hpp>
12873 
12874 // #include <nlohmann/detail/input/lexer.hpp>
12875 
12876 // #include <nlohmann/detail/macro_scope.hpp>
12877 
12878 // #include <nlohmann/detail/meta/is_sax.hpp>
12879 
12880 // #include <nlohmann/detail/string_concat.hpp>
12881 
12882 // #include <nlohmann/detail/value_t.hpp>
12883 
12884 
12886 namespace detail
12887 {
12889 // parser //
12891 
12892 enum class parse_event_t : std::uint8_t
12893 {
12895  object_start,
12897  object_end,
12899  array_start,
12901  array_end,
12903  key,
12905  value
12906 };
12907 
12908 template<typename BasicJsonType>
12910  std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
12911 
12917 template<typename BasicJsonType, typename InputAdapterType>
12918 class parser
12919 {
12920  using number_integer_t = typename BasicJsonType::number_integer_t;
12921  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12922  using number_float_t = typename BasicJsonType::number_float_t;
12923  using string_t = typename BasicJsonType::string_t;
12925  using token_type = typename lexer_t::token_type;
12926 
12927  public:
12929  explicit parser(InputAdapterType&& adapter,
12930  parser_callback_t<BasicJsonType> cb = nullptr,
12931  const bool allow_exceptions_ = true,
12932  const bool skip_comments = false)
12933  : callback(std::move(cb))
12934  , m_lexer(std::move(adapter), skip_comments)
12935  , allow_exceptions(allow_exceptions_)
12936  {
12937  // read first token
12938  get_token();
12939  }
12940 
12951  void parse(const bool strict, BasicJsonType& result)
12952  {
12953  if (callback)
12954  {
12955  json_sax_dom_callback_parser<BasicJsonType, InputAdapterType> sdp(result, callback, allow_exceptions, &m_lexer);
12956  sax_parse_internal(&sdp);
12957 
12958  // in strict mode, input must be completely read
12959  if (strict && (get_token() != token_type::end_of_input))
12960  {
12961  sdp.parse_error(m_lexer.get_position(),
12962  m_lexer.get_token_string(),
12963  parse_error::create(101, m_lexer.get_position(),
12964  exception_message(token_type::end_of_input, "value"), nullptr));
12965  }
12966 
12967  // in case of an error, return discarded value
12968  if (sdp.is_errored())
12969  {
12970  result = value_t::discarded;
12971  return;
12972  }
12973 
12974  // set top-level value to null if it was discarded by the callback
12975  // function
12976  if (result.is_discarded())
12977  {
12978  result = nullptr;
12979  }
12980  }
12981  else
12982  {
12983  json_sax_dom_parser<BasicJsonType, InputAdapterType> sdp(result, allow_exceptions, &m_lexer);
12984  sax_parse_internal(&sdp);
12985 
12986  // in strict mode, input must be completely read
12987  if (strict && (get_token() != token_type::end_of_input))
12988  {
12989  sdp.parse_error(m_lexer.get_position(),
12990  m_lexer.get_token_string(),
12991  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12992  }
12993 
12994  // in case of an error, return discarded value
12995  if (sdp.is_errored())
12996  {
12997  result = value_t::discarded;
12998  return;
12999  }
13000  }
13001 
13002  result.assert_invariant();
13003  }
13004 
13011  bool accept(const bool strict = true)
13012  {
13013  json_sax_acceptor<BasicJsonType> sax_acceptor;
13014  return sax_parse(&sax_acceptor, strict);
13015  }
13016 
13017  template<typename SAX>
13019  bool sax_parse(SAX* sax, const bool strict = true)
13020  {
13022  const bool result = sax_parse_internal(sax);
13023 
13024  // strict mode: next byte must be EOF
13025  if (result && strict && (get_token() != token_type::end_of_input))
13026  {
13027  return sax->parse_error(m_lexer.get_position(),
13028  m_lexer.get_token_string(),
13029  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
13030  }
13031 
13032  return result;
13033  }
13034 
13035  private:
13036  template<typename SAX>
13038  bool sax_parse_internal(SAX* sax)
13039  {
13040  // stack to remember the hierarchy of structured values we are parsing
13041  // true = array; false = object
13042  std::vector<bool> states;
13043  // value to avoid a goto (see comment where set to true)
13044  bool skip_to_state_evaluation = false;
13045 
13046  while (true)
13047  {
13048  if (!skip_to_state_evaluation)
13049  {
13050  // invariant: get_token() was called before each iteration
13051  switch (last_token)
13052  {
13053  case token_type::begin_object:
13054  {
13055  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size())))
13056  {
13057  return false;
13058  }
13059 
13060  // closing } -> we are done
13061  if (get_token() == token_type::end_object)
13062  {
13063  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
13064  {
13065  return false;
13066  }
13067  break;
13068  }
13069 
13070  // parse key
13071  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
13072  {
13073  return sax->parse_error(m_lexer.get_position(),
13074  m_lexer.get_token_string(),
13075  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
13076  }
13077  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
13078  {
13079  return false;
13080  }
13081 
13082  // parse separator (:)
13083  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
13084  {
13085  return sax->parse_error(m_lexer.get_position(),
13086  m_lexer.get_token_string(),
13087  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
13088  }
13089 
13090  // remember we are now inside an object
13091  states.push_back(false);
13092 
13093  // parse values
13094  get_token();
13095  continue;
13096  }
13097 
13098  case token_type::begin_array:
13099  {
13100  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size())))
13101  {
13102  return false;
13103  }
13104 
13105  // closing ] -> we are done
13106  if (get_token() == token_type::end_array)
13107  {
13108  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
13109  {
13110  return false;
13111  }
13112  break;
13113  }
13114 
13115  // remember we are now inside an array
13116  states.push_back(true);
13117 
13118  // parse values (no need to call get_token)
13119  continue;
13120  }
13121 
13122  case token_type::value_float:
13123  {
13124  const auto res = m_lexer.get_number_float();
13125 
13126  if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
13127  {
13128  return sax->parse_error(m_lexer.get_position(),
13129  m_lexer.get_token_string(),
13130  out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
13131  }
13132 
13133  if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
13134  {
13135  return false;
13136  }
13137 
13138  break;
13139  }
13140 
13141  case token_type::literal_false:
13142  {
13143  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
13144  {
13145  return false;
13146  }
13147  break;
13148  }
13149 
13150  case token_type::literal_null:
13151  {
13152  if (JSON_HEDLEY_UNLIKELY(!sax->null()))
13153  {
13154  return false;
13155  }
13156  break;
13157  }
13158 
13159  case token_type::literal_true:
13160  {
13161  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
13162  {
13163  return false;
13164  }
13165  break;
13166  }
13167 
13168  case token_type::value_integer:
13169  {
13170  if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
13171  {
13172  return false;
13173  }
13174  break;
13175  }
13176 
13177  case token_type::value_string:
13178  {
13179  if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
13180  {
13181  return false;
13182  }
13183  break;
13184  }
13185 
13186  case token_type::value_unsigned:
13187  {
13188  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
13189  {
13190  return false;
13191  }
13192  break;
13193  }
13194 
13195  case token_type::parse_error:
13196  {
13197  // using "uninitialized" to avoid "expected" message
13198  return sax->parse_error(m_lexer.get_position(),
13199  m_lexer.get_token_string(),
13200  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
13201  }
13202  case token_type::end_of_input:
13203  {
13204  if (JSON_HEDLEY_UNLIKELY(m_lexer.get_position().chars_read_total == 1))
13205  {
13206  return sax->parse_error(m_lexer.get_position(),
13207  m_lexer.get_token_string(),
13208  parse_error::create(101, m_lexer.get_position(),
13209  "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
13210  }
13211 
13212  return sax->parse_error(m_lexer.get_position(),
13213  m_lexer.get_token_string(),
13214  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
13215  }
13216  case token_type::uninitialized:
13217  case token_type::end_array:
13218  case token_type::end_object:
13219  case token_type::name_separator:
13220  case token_type::value_separator:
13221  case token_type::literal_or_value:
13222  default: // the last token was unexpected
13223  {
13224  return sax->parse_error(m_lexer.get_position(),
13225  m_lexer.get_token_string(),
13226  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
13227  }
13228  }
13229  }
13230  else
13231  {
13232  skip_to_state_evaluation = false;
13233  }
13234 
13235  // we reached this line after we successfully parsed a value
13236  if (states.empty())
13237  {
13238  // empty stack: we reached the end of the hierarchy: done
13239  return true;
13240  }
13241 
13242  if (states.back()) // array
13243  {
13244  // comma -> next value
13245  if (get_token() == token_type::value_separator)
13246  {
13247  // parse a new value
13248  get_token();
13249  continue;
13250  }
13251 
13252  // closing ]
13253  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
13254  {
13255  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
13256  {
13257  return false;
13258  }
13259 
13260  // We are done with this array. Before we can parse a
13261  // new value, we need to evaluate the new state first.
13262  // By setting skip_to_state_evaluation to false, we
13263  // are effectively jumping to the beginning of this if.
13264  JSON_ASSERT(!states.empty());
13265  states.pop_back();
13266  skip_to_state_evaluation = true;
13267  continue;
13268  }
13269 
13270  return sax->parse_error(m_lexer.get_position(),
13271  m_lexer.get_token_string(),
13272  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
13273  }
13274 
13275  // states.back() is false -> object
13276 
13277  // comma -> next value
13278  if (get_token() == token_type::value_separator)
13279  {
13280  // parse key
13281  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
13282  {
13283  return sax->parse_error(m_lexer.get_position(),
13284  m_lexer.get_token_string(),
13285  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
13286  }
13287 
13288  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
13289  {
13290  return false;
13291  }
13292 
13293  // parse separator (:)
13294  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
13295  {
13296  return sax->parse_error(m_lexer.get_position(),
13297  m_lexer.get_token_string(),
13298  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
13299  }
13300 
13301  // parse values
13302  get_token();
13303  continue;
13304  }
13305 
13306  // closing }
13307  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
13308  {
13309  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
13310  {
13311  return false;
13312  }
13313 
13314  // We are done with this object. Before we can parse a
13315  // new value, we need to evaluate the new state first.
13316  // By setting skip_to_state_evaluation to false, we
13317  // are effectively jumping to the beginning of this if.
13318  JSON_ASSERT(!states.empty());
13319  states.pop_back();
13320  skip_to_state_evaluation = true;
13321  continue;
13322  }
13323 
13324  return sax->parse_error(m_lexer.get_position(),
13325  m_lexer.get_token_string(),
13326  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
13327  }
13328  }
13329 
13331  token_type get_token()
13332  {
13333  return last_token = m_lexer.scan();
13334  }
13335 
13336  std::string exception_message(const token_type expected, const std::string& context)
13337  {
13338  std::string error_msg = "syntax error ";
13339 
13340  if (!context.empty())
13341  {
13342  error_msg += concat("while parsing ", context, ' ');
13343  }
13344 
13345  error_msg += "- ";
13346 
13347  if (last_token == token_type::parse_error)
13348  {
13349  error_msg += concat(m_lexer.get_error_message(), "; last read: '",
13350  m_lexer.get_token_string(), '\'');
13351  }
13352  else
13353  {
13354  error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
13355  }
13356 
13357  if (expected != token_type::uninitialized)
13358  {
13359  error_msg += concat("; expected ", lexer_t::token_type_name(expected));
13360  }
13361 
13362  return error_msg;
13363  }
13364 
13365  private:
13367  const parser_callback_t<BasicJsonType> callback = nullptr;
13369  token_type last_token = token_type::uninitialized;
13371  lexer_t m_lexer;
13373  const bool allow_exceptions = true;
13374 };
13375 
13376 } // namespace detail
13378 
13379 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
13380 // __ _____ _____ _____
13381 // __| | __| | | | JSON for Modern C++
13382 // | | |__ | | | | | | version 3.12.0
13383 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13384 //
13385 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
13386 // SPDX-License-Identifier: MIT
13387 
13388 
13389 
13390 // #include <nlohmann/detail/abi_macros.hpp>
13391 
13392 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13393 // __ _____ _____ _____
13394 // __| | __| | | | JSON for Modern C++
13395 // | | |__ | | | | | | version 3.12.0
13396 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13397 //
13398 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
13399 // SPDX-License-Identifier: MIT
13400 
13401 
13402 
13403 #include <cstddef> // ptrdiff_t
13404 #include <limits> // numeric_limits
13405 
13406 // #include <nlohmann/detail/macro_scope.hpp>
13407 
13408 
13410 namespace detail
13411 {
13412 
13413 /*
13414 @brief an iterator for primitive JSON types
13415 
13416 This class models an iterator for primitive JSON types (boolean, number,
13417 string). It's only purpose is to allow the iterator/const_iterator classes
13418 to "iterate" over primitive values. Internally, the iterator is modeled by
13419 a `difference_type` variable. Value begin_value (`0`) models the begin,
13420 end_value (`1`) models past the end.
13421 */
13423 {
13424  private:
13425  using difference_type = std::ptrdiff_t;
13426  static constexpr difference_type begin_value = 0;
13427  static constexpr difference_type end_value = begin_value + 1;
13428 
13431  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
13432 
13433  public:
13434  constexpr difference_type get_value() const noexcept
13435  {
13436  return m_it;
13437  }
13438 
13440  void set_begin() noexcept
13441  {
13442  m_it = begin_value;
13443  }
13444 
13446  void set_end() noexcept
13447  {
13448  m_it = end_value;
13449  }
13450 
13452  constexpr bool is_begin() const noexcept
13453  {
13454  return m_it == begin_value;
13455  }
13456 
13458  constexpr bool is_end() const noexcept
13459  {
13460  return m_it == end_value;
13461  }
13462 
13463  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
13464  {
13465  return lhs.m_it == rhs.m_it;
13466  }
13467 
13468  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
13469  {
13470  return lhs.m_it < rhs.m_it;
13471  }
13472 
13473  primitive_iterator_t operator+(difference_type n) noexcept
13474  {
13475  auto result = *this;
13476  result += n;
13477  return result;
13478  }
13479 
13480  friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
13481  {
13482  return lhs.m_it - rhs.m_it;
13483  }
13484 
13486  {
13487  ++m_it;
13488  return *this;
13489  }
13490 
13491  primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
13492  {
13493  auto result = *this;
13494  ++m_it;
13495  return result;
13496  }
13497 
13499  {
13500  --m_it;
13501  return *this;
13502  }
13503 
13504  primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
13505  {
13506  auto result = *this;
13507  --m_it;
13508  return result;
13509  }
13510 
13511  primitive_iterator_t& operator+=(difference_type n) noexcept
13512  {
13513  m_it += n;
13514  return *this;
13515  }
13516 
13517  primitive_iterator_t& operator-=(difference_type n) noexcept
13518  {
13519  m_it -= n;
13520  return *this;
13521  }
13522 };
13523 
13524 } // namespace detail
13526 
13527 
13529 namespace detail
13530 {
13531 
13538 template<typename BasicJsonType> struct internal_iterator
13539 {
13541  typename BasicJsonType::object_t::iterator object_iterator {};
13543  typename BasicJsonType::array_t::iterator array_iterator {};
13545  primitive_iterator_t primitive_iterator {};
13546 };
13547 
13548 } // namespace detail
13550 
13551 // #include <nlohmann/detail/iterators/iter_impl.hpp>
13552 // __ _____ _____ _____
13553 // __| | __| | | | JSON for Modern C++
13554 // | | |__ | | | | | | version 3.12.0
13555 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
13556 //
13557 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
13558 // SPDX-License-Identifier: MIT
13559 
13560 
13561 
13562 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
13563 #include <type_traits> // conditional, is_const, remove_const
13564 
13565 // #include <nlohmann/detail/exceptions.hpp>
13566 
13567 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
13568 
13569 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13570 
13571 // #include <nlohmann/detail/macro_scope.hpp>
13572 
13573 // #include <nlohmann/detail/meta/cpp_future.hpp>
13574 
13575 // #include <nlohmann/detail/meta/type_traits.hpp>
13576 
13577 // #include <nlohmann/detail/value_t.hpp>
13578 
13579 
13581 namespace detail
13582 {
13583 
13584 // forward declare, to be able to friend it later on
13585 template<typename IteratorType> class iteration_proxy;
13586 template<typename IteratorType> class iteration_proxy_value;
13587 
13604 template<typename BasicJsonType>
13605 class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
13606 {
13608  using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
13610  friend other_iter_impl;
13611  friend BasicJsonType;
13614 
13615  using object_t = typename BasicJsonType::object_t;
13616  using array_t = typename BasicJsonType::array_t;
13617  // make sure BasicJsonType is basic_json or const basic_json
13618  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
13619  "iter_impl only accepts (const) basic_json");
13620  // superficial check for the LegacyBidirectionalIterator named requirement
13621  static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
13622  && std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
13623  "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
13624 
13625  public:
13631  using iterator_category = std::bidirectional_iterator_tag;
13632 
13634  using value_type = typename BasicJsonType::value_type;
13636  using difference_type = typename BasicJsonType::difference_type;
13638  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
13639  typename BasicJsonType::const_pointer,
13640  typename BasicJsonType::pointer>::type;
13642  using reference =
13643  typename std::conditional<std::is_const<BasicJsonType>::value,
13644  typename BasicJsonType::const_reference,
13645  typename BasicJsonType::reference>::type;
13646 
13647  iter_impl() = default;
13648  ~iter_impl() = default;
13649  iter_impl(iter_impl&&) noexcept = default;
13650  iter_impl& operator=(iter_impl&&) noexcept = default;
13651 
13658  explicit iter_impl(pointer object) noexcept : m_object(object)
13659  {
13660  JSON_ASSERT(m_object != nullptr);
13661 
13662  switch (m_object->m_data.m_type)
13663  {
13664  case value_t::object:
13665  {
13666  m_it.object_iterator = typename object_t::iterator();
13667  break;
13668  }
13669 
13670  case value_t::array:
13671  {
13672  m_it.array_iterator = typename array_t::iterator();
13673  break;
13674  }
13675 
13676  case value_t::null:
13677  case value_t::string:
13678  case value_t::boolean:
13679  case value_t::number_integer:
13680  case value_t::number_unsigned:
13681  case value_t::number_float:
13682  case value_t::binary:
13683  case value_t::discarded:
13684  default:
13685  {
13686  m_it.primitive_iterator = primitive_iterator_t();
13687  break;
13688  }
13689  }
13690  }
13691 
13709  : m_object(other.m_object), m_it(other.m_it)
13710  {}
13711 
13719  {
13720  if (&other != this)
13721  {
13722  m_object = other.m_object;
13723  m_it = other.m_it;
13724  }
13725  return *this;
13726  }
13727 
13733  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
13734  : m_object(other.m_object), m_it(other.m_it)
13735  {}
13736 
13743  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
13744  {
13745  m_object = other.m_object;
13746  m_it = other.m_it;
13747  return *this;
13748  }
13749 
13755  void set_begin() noexcept
13756  {
13757  JSON_ASSERT(m_object != nullptr);
13758 
13759  switch (m_object->m_data.m_type)
13760  {
13761  case value_t::object:
13762  {
13763  m_it.object_iterator = m_object->m_data.m_value.object->begin();
13764  break;
13765  }
13766 
13767  case value_t::array:
13768  {
13769  m_it.array_iterator = m_object->m_data.m_value.array->begin();
13770  break;
13771  }
13772 
13773  case value_t::null:
13774  {
13775  // set to end so begin()==end() is true: null is empty
13776  m_it.primitive_iterator.set_end();
13777  break;
13778  }
13779 
13780  case value_t::string:
13781  case value_t::boolean:
13782  case value_t::number_integer:
13783  case value_t::number_unsigned:
13784  case value_t::number_float:
13785  case value_t::binary:
13786  case value_t::discarded:
13787  default:
13788  {
13789  m_it.primitive_iterator.set_begin();
13790  break;
13791  }
13792  }
13793  }
13794 
13799  void set_end() noexcept
13800  {
13801  JSON_ASSERT(m_object != nullptr);
13802 
13803  switch (m_object->m_data.m_type)
13804  {
13805  case value_t::object:
13806  {
13807  m_it.object_iterator = m_object->m_data.m_value.object->end();
13808  break;
13809  }
13810 
13811  case value_t::array:
13812  {
13813  m_it.array_iterator = m_object->m_data.m_value.array->end();
13814  break;
13815  }
13816 
13817  case value_t::null:
13818  case value_t::string:
13819  case value_t::boolean:
13820  case value_t::number_integer:
13821  case value_t::number_unsigned:
13822  case value_t::number_float:
13823  case value_t::binary:
13824  case value_t::discarded:
13825  default:
13826  {
13827  m_it.primitive_iterator.set_end();
13828  break;
13829  }
13830  }
13831  }
13832 
13833  public:
13839  {
13840  JSON_ASSERT(m_object != nullptr);
13841 
13842  switch (m_object->m_data.m_type)
13843  {
13844  case value_t::object:
13845  {
13846  JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13847  return m_it.object_iterator->second;
13848  }
13849 
13850  case value_t::array:
13851  {
13852  JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13853  return *m_it.array_iterator;
13854  }
13855 
13856  case value_t::null:
13857  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13858 
13859  case value_t::string:
13860  case value_t::boolean:
13861  case value_t::number_integer:
13862  case value_t::number_unsigned:
13863  case value_t::number_float:
13864  case value_t::binary:
13865  case value_t::discarded:
13866  default:
13867  {
13868  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13869  {
13870  return *m_object;
13871  }
13872 
13873  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13874  }
13875  }
13876  }
13877 
13883  {
13884  JSON_ASSERT(m_object != nullptr);
13885 
13886  switch (m_object->m_data.m_type)
13887  {
13888  case value_t::object:
13889  {
13890  JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13891  return &(m_it.object_iterator->second);
13892  }
13893 
13894  case value_t::array:
13895  {
13896  JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13897  return &*m_it.array_iterator;
13898  }
13899 
13900  case value_t::null:
13901  case value_t::string:
13902  case value_t::boolean:
13903  case value_t::number_integer:
13904  case value_t::number_unsigned:
13905  case value_t::number_float:
13906  case value_t::binary:
13907  case value_t::discarded:
13908  default:
13909  {
13910  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13911  {
13912  return m_object;
13913  }
13914 
13915  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13916  }
13917  }
13918  }
13919 
13924  iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
13925  {
13926  auto result = *this;
13927  ++(*this);
13928  return result;
13929  }
13930 
13936  {
13937  JSON_ASSERT(m_object != nullptr);
13938 
13939  switch (m_object->m_data.m_type)
13940  {
13941  case value_t::object:
13942  {
13943  std::advance(m_it.object_iterator, 1);
13944  break;
13945  }
13946 
13947  case value_t::array:
13948  {
13949  std::advance(m_it.array_iterator, 1);
13950  break;
13951  }
13952 
13953  case value_t::null:
13954  case value_t::string:
13955  case value_t::boolean:
13956  case value_t::number_integer:
13957  case value_t::number_unsigned:
13958  case value_t::number_float:
13959  case value_t::binary:
13960  case value_t::discarded:
13961  default:
13962  {
13963  ++m_it.primitive_iterator;
13964  break;
13965  }
13966  }
13967 
13968  return *this;
13969  }
13970 
13975  iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
13976  {
13977  auto result = *this;
13978  --(*this);
13979  return result;
13980  }
13981 
13987  {
13988  JSON_ASSERT(m_object != nullptr);
13989 
13990  switch (m_object->m_data.m_type)
13991  {
13992  case value_t::object:
13993  {
13994  std::advance(m_it.object_iterator, -1);
13995  break;
13996  }
13997 
13998  case value_t::array:
13999  {
14000  std::advance(m_it.array_iterator, -1);
14001  break;
14002  }
14003 
14004  case value_t::null:
14005  case value_t::string:
14006  case value_t::boolean:
14007  case value_t::number_integer:
14008  case value_t::number_unsigned:
14009  case value_t::number_float:
14010  case value_t::binary:
14011  case value_t::discarded:
14012  default:
14013  {
14014  --m_it.primitive_iterator;
14015  break;
14016  }
14017  }
14018 
14019  return *this;
14020  }
14021 
14026  template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
14027  bool operator==(const IterImpl& other) const
14028  {
14029  // if objects are not the same, the comparison is undefined
14030  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
14031  {
14032  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
14033  }
14034 
14035  // value-initialized forward iterators can be compared, and must compare equal to other value-initialized iterators of the same type #4493
14036  if (m_object == nullptr)
14037  {
14038  return true;
14039  }
14040 
14041  switch (m_object->m_data.m_type)
14042  {
14043  case value_t::object:
14044  return (m_it.object_iterator == other.m_it.object_iterator);
14045 
14046  case value_t::array:
14047  return (m_it.array_iterator == other.m_it.array_iterator);
14048 
14049  case value_t::null:
14050  case value_t::string:
14051  case value_t::boolean:
14052  case value_t::number_integer:
14053  case value_t::number_unsigned:
14054  case value_t::number_float:
14055  case value_t::binary:
14056  case value_t::discarded:
14057  default:
14058  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
14059  }
14060  }
14061 
14066  template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
14067  bool operator!=(const IterImpl& other) const
14068  {
14069  return !operator==(other);
14070  }
14071 
14076  bool operator<(const iter_impl& other) const
14077  {
14078  // if objects are not the same, the comparison is undefined
14079  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
14080  {
14081  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
14082  }
14083 
14084  // value-initialized forward iterators can be compared, and must compare equal to other value-initialized iterators of the same type #4493
14085  if (m_object == nullptr)
14086  {
14087  // the iterators are both value-initialized and are to be considered equal, but this function checks for smaller, so we return false
14088  return false;
14089  }
14090 
14091  switch (m_object->m_data.m_type)
14092  {
14093  case value_t::object:
14094  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
14095 
14096  case value_t::array:
14097  return (m_it.array_iterator < other.m_it.array_iterator);
14098 
14099  case value_t::null:
14100  case value_t::string:
14101  case value_t::boolean:
14102  case value_t::number_integer:
14103  case value_t::number_unsigned:
14104  case value_t::number_float:
14105  case value_t::binary:
14106  case value_t::discarded:
14107  default:
14108  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
14109  }
14110  }
14111 
14116  bool operator<=(const iter_impl& other) const
14117  {
14118  return !other.operator < (*this);
14119  }
14120 
14125  bool operator>(const iter_impl& other) const
14126  {
14127  return !operator<=(other);
14128  }
14129 
14134  bool operator>=(const iter_impl& other) const
14135  {
14136  return !operator<(other);
14137  }
14138 
14144  {
14145  JSON_ASSERT(m_object != nullptr);
14146 
14147  switch (m_object->m_data.m_type)
14148  {
14149  case value_t::object:
14150  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
14151 
14152  case value_t::array:
14153  {
14154  std::advance(m_it.array_iterator, i);
14155  break;
14156  }
14157 
14158  case value_t::null:
14159  case value_t::string:
14160  case value_t::boolean:
14161  case value_t::number_integer:
14162  case value_t::number_unsigned:
14163  case value_t::number_float:
14164  case value_t::binary:
14165  case value_t::discarded:
14166  default:
14167  {
14168  m_it.primitive_iterator += i;
14169  break;
14170  }
14171  }
14172 
14173  return *this;
14174  }
14175 
14181  {
14182  return operator+=(-i);
14183  }
14184 
14190  {
14191  auto result = *this;
14192  result += i;
14193  return result;
14194  }
14195 
14201  {
14202  auto result = it;
14203  result += i;
14204  return result;
14205  }
14206 
14212  {
14213  auto result = *this;
14214  result -= i;
14215  return result;
14216  }
14217 
14223  {
14224  JSON_ASSERT(m_object != nullptr);
14225 
14226  switch (m_object->m_data.m_type)
14227  {
14228  case value_t::object:
14229  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
14230 
14231  case value_t::array:
14232  return m_it.array_iterator - other.m_it.array_iterator;
14233 
14234  case value_t::null:
14235  case value_t::string:
14236  case value_t::boolean:
14237  case value_t::number_integer:
14238  case value_t::number_unsigned:
14239  case value_t::number_float:
14240  case value_t::binary:
14241  case value_t::discarded:
14242  default:
14243  return m_it.primitive_iterator - other.m_it.primitive_iterator;
14244  }
14245  }
14246 
14252  {
14253  JSON_ASSERT(m_object != nullptr);
14254 
14255  switch (m_object->m_data.m_type)
14256  {
14257  case value_t::object:
14258  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
14259 
14260  case value_t::array:
14261  return *std::next(m_it.array_iterator, n);
14262 
14263  case value_t::null:
14264  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
14265 
14266  case value_t::string:
14267  case value_t::boolean:
14268  case value_t::number_integer:
14269  case value_t::number_unsigned:
14270  case value_t::number_float:
14271  case value_t::binary:
14272  case value_t::discarded:
14273  default:
14274  {
14275  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
14276  {
14277  return *m_object;
14278  }
14279 
14280  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
14281  }
14282  }
14283  }
14284 
14289  const typename object_t::key_type& key() const
14290  {
14291  JSON_ASSERT(m_object != nullptr);
14292 
14293  if (JSON_HEDLEY_LIKELY(m_object->is_object()))
14294  {
14295  return m_it.object_iterator->first;
14296  }
14297 
14298  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
14299  }
14300 
14306  {
14307  return operator*();
14308  }
14309 
14312  pointer m_object = nullptr;
14315 };
14316 
14317 } // namespace detail
14319 
14320 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
14321 
14322 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
14323 // __ _____ _____ _____
14324 // __| | __| | | | JSON for Modern C++
14325 // | | |__ | | | | | | version 3.12.0
14326 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14327 //
14328 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
14329 // SPDX-License-Identifier: MIT
14330 
14331 
14332 
14333 #include <cstddef> // ptrdiff_t
14334 #include <iterator> // reverse_iterator
14335 #include <utility> // declval
14336 
14337 // #include <nlohmann/detail/abi_macros.hpp>
14338 
14339 
14341 namespace detail
14342 {
14343 
14345 // reverse_iterator //
14347 
14366 template<typename Base>
14367 class json_reverse_iterator : public std::reverse_iterator<Base>
14368 {
14369  public:
14370  using difference_type = std::ptrdiff_t;
14372  using base_iterator = std::reverse_iterator<Base>;
14374  using reference = typename Base::reference;
14375 
14377  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
14378  : base_iterator(it) {}
14379 
14381  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
14382 
14384  json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
14385  {
14386  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
14387  }
14388 
14391  {
14392  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
14393  }
14394 
14396  json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
14397  {
14398  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
14399  }
14400 
14403  {
14404  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
14405  }
14406 
14409  {
14410  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
14411  }
14412 
14415  {
14416  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
14417  }
14418 
14421  {
14422  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
14423  }
14424 
14427  {
14428  return base_iterator(*this) - base_iterator(other);
14429  }
14430 
14433  {
14434  return *(this->operator+(n));
14435  }
14436 
14438  auto key() const -> decltype(std::declval<Base>().key())
14439  {
14440  auto it = --this->base();
14441  return it.key();
14442  }
14443 
14446  {
14447  auto it = --this->base();
14448  return it.operator * ();
14449  }
14450 };
14451 
14452 } // namespace detail
14454 
14455 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
14456 
14457 // #include <nlohmann/detail/json_custom_base_class.hpp>
14458 // __ _____ _____ _____
14459 // __| | __| | | | JSON for Modern C++
14460 // | | |__ | | | | | | version 3.12.0
14461 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14462 //
14463 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
14464 // SPDX-License-Identifier: MIT
14465 
14466 
14467 
14468 #include <type_traits> // conditional, is_same
14469 
14470 // #include <nlohmann/detail/abi_macros.hpp>
14471 
14472 
14474 namespace detail
14475 {
14476 
14488 
14489 template<class T>
14490 using json_base_class = typename std::conditional <
14491  std::is_same<T, void>::value,
14493  T
14494  >::type;
14495 
14496 } // namespace detail
14498 
14499 // #include <nlohmann/detail/json_pointer.hpp>
14500 // __ _____ _____ _____
14501 // __| | __| | | | JSON for Modern C++
14502 // | | |__ | | | | | | version 3.12.0
14503 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
14504 //
14505 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
14506 // SPDX-License-Identifier: MIT
14507 
14508 
14509 
14510 #include <algorithm> // all_of
14511 #include <cctype> // isdigit
14512 #include <cerrno> // errno, ERANGE
14513 #include <cstdlib> // strtoull
14514 #ifndef JSON_NO_IO
14515  #include <iosfwd> // ostream
14516 #endif // JSON_NO_IO
14517 #include <limits> // max
14518 #include <numeric> // accumulate
14519 #include <string> // string
14520 #include <utility> // move
14521 #include <vector> // vector
14522 
14523 // #include <nlohmann/detail/exceptions.hpp>
14524 
14525 // #include <nlohmann/detail/macro_scope.hpp>
14526 
14527 // #include <nlohmann/detail/string_concat.hpp>
14528 
14529 // #include <nlohmann/detail/string_escape.hpp>
14530 
14531 // #include <nlohmann/detail/value_t.hpp>
14532 
14533 
14535 
14538 template<typename RefStringType>
14540 {
14541  // allow basic_json to access private members
14543  friend class basic_json;
14544 
14545  template<typename>
14546  friend class json_pointer;
14547 
14548  template<typename T>
14549  struct string_t_helper
14550  {
14551  using type = T;
14552  };
14553 
14555  struct string_t_helper<NLOHMANN_BASIC_JSON_TPL>
14556  {
14557  using type = StringType;
14558  };
14559 
14560  public:
14561  // for backwards compatibility accept BasicJsonType
14562  using string_t = typename string_t_helper<RefStringType>::type;
14563 
14566  explicit json_pointer(const string_t& s = "")
14567  : reference_tokens(split(s))
14568  {}
14569 
14573  {
14574  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
14575  string_t{},
14576  [](const string_t& a, const string_t& b)
14577  {
14578  return detail::concat(a, '/', detail::escape(b));
14579  });
14580  }
14581 
14585  operator string_t() const
14586  {
14587  return to_string();
14588  }
14589 
14590 #ifndef JSON_NO_IO
14593  friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
14594  {
14595  o << ptr.to_string();
14596  return o;
14597  }
14598 #endif
14599 
14603  {
14604  reference_tokens.insert(reference_tokens.end(),
14605  ptr.reference_tokens.begin(),
14606  ptr.reference_tokens.end());
14607  return *this;
14608  }
14609 
14613  {
14614  push_back(std::move(token));
14615  return *this;
14616  }
14617 
14620  json_pointer& operator/=(std::size_t array_idx)
14621  {
14622  return *this /= std::to_string(array_idx);
14623  }
14624 
14628  const json_pointer& rhs)
14629  {
14630  return json_pointer(lhs) /= rhs;
14631  }
14632 
14635  friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
14636  {
14637  return json_pointer(lhs) /= std::move(token);
14638  }
14639 
14642  friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
14643  {
14644  return json_pointer(lhs) /= array_idx;
14645  }
14646 
14650  {
14651  if (empty())
14652  {
14653  return *this;
14654  }
14655 
14656  json_pointer res = *this;
14657  res.pop_back();
14658  return res;
14659  }
14660 
14663  void pop_back()
14664  {
14665  if (JSON_HEDLEY_UNLIKELY(empty()))
14666  {
14667  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
14668  }
14669 
14670  reference_tokens.pop_back();
14671  }
14672 
14675  const string_t& back() const
14676  {
14677  if (JSON_HEDLEY_UNLIKELY(empty()))
14678  {
14679  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
14680  }
14681 
14682  return reference_tokens.back();
14683  }
14684 
14687  void push_back(const string_t& token)
14688  {
14689  reference_tokens.push_back(token);
14690  }
14691 
14694  void push_back(string_t&& token)
14695  {
14696  reference_tokens.push_back(std::move(token));
14697  }
14698 
14701  bool empty() const noexcept
14702  {
14703  return reference_tokens.empty();
14704  }
14705 
14706  private:
14717  template<typename BasicJsonType>
14718  static typename BasicJsonType::size_type array_index(const string_t& s)
14719  {
14720  using size_type = typename BasicJsonType::size_type;
14721 
14722  // error condition (cf. RFC 6901, Sect. 4)
14723  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
14724  {
14725  JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
14726  }
14727 
14728  // error condition (cf. RFC 6901, Sect. 4)
14729  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
14730  {
14731  JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
14732  }
14733 
14734  const char* p = s.c_str();
14735  char* p_end = nullptr; // NOLINT(misc-const-correctness)
14736  errno = 0; // strtoull doesn't reset errno
14737  const unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
14738  if (p == p_end // invalid input or empty string
14739  || errno == ERANGE // out of range
14740  || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
14741  {
14742  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
14743  }
14744 
14745  // only triggered on special platforms (like 32bit), see also
14746  // https://github.com/nlohmann/json/pull/2203
14747  if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
14748  {
14749  JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
14750  }
14751 
14752  return static_cast<size_type>(res);
14753  }
14754 
14756  json_pointer top() const
14757  {
14758  if (JSON_HEDLEY_UNLIKELY(empty()))
14759  {
14760  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
14761  }
14762 
14763  json_pointer result = *this;
14764  result.reference_tokens = {reference_tokens[0]};
14765  return result;
14766  }
14767 
14768  private:
14777  template<typename BasicJsonType>
14778  BasicJsonType& get_and_create(BasicJsonType& j) const
14779  {
14780  auto* result = &j;
14781 
14782  // in case no reference tokens exist, return a reference to the JSON value
14783  // j which will be overwritten by a primitive value
14784  for (const auto& reference_token : reference_tokens)
14785  {
14786  switch (result->type())
14787  {
14788  case detail::value_t::null:
14789  {
14790  if (reference_token == "0")
14791  {
14792  // start a new array if reference token is 0
14793  result = &result->operator[](0);
14794  }
14795  else
14796  {
14797  // start a new object otherwise
14798  result = &result->operator[](reference_token);
14799  }
14800  break;
14801  }
14802 
14804  {
14805  // create an entry in the object
14806  result = &result->operator[](reference_token);
14807  break;
14808  }
14809 
14811  {
14812  // create an entry in the array
14813  result = &result->operator[](array_index<BasicJsonType>(reference_token));
14814  break;
14815  }
14816 
14817  /*
14818  The following code is only reached if there exists a reference
14819  token _and_ the current value is primitive. In this case, we have
14820  an error situation, because primitive values may only occur as
14821  single value; that is, with an empty list of reference tokens.
14822  */
14830  default:
14831  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
14832  }
14833  }
14834 
14835  return *result;
14836  }
14837 
14857  template<typename BasicJsonType>
14858  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
14859  {
14860  for (const auto& reference_token : reference_tokens)
14861  {
14862  // convert null values to arrays or objects before continuing
14863  if (ptr->is_null())
14864  {
14865  // check if reference token is a number
14866  const bool nums =
14867  std::all_of(reference_token.begin(), reference_token.end(),
14868  [](const unsigned char x)
14869  {
14870  return std::isdigit(x);
14871  });
14872 
14873  // change value to array for numbers or "-" or to object otherwise
14874  *ptr = (nums || reference_token == "-")
14877  }
14878 
14879  switch (ptr->type())
14880  {
14882  {
14883  // use unchecked object access
14884  ptr = &ptr->operator[](reference_token);
14885  break;
14886  }
14887 
14889  {
14890  if (reference_token == "-")
14891  {
14892  // explicitly treat "-" as index beyond the end
14893  ptr = &ptr->operator[](ptr->m_data.m_value.array->size());
14894  }
14895  else
14896  {
14897  // convert array index to number; unchecked access
14898  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14899  }
14900  break;
14901  }
14902 
14903  case detail::value_t::null:
14911  default:
14912  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14913  }
14914  }
14915 
14916  return *ptr;
14917  }
14918 
14925  template<typename BasicJsonType>
14926  BasicJsonType& get_checked(BasicJsonType* ptr) const
14927  {
14928  for (const auto& reference_token : reference_tokens)
14929  {
14930  switch (ptr->type())
14931  {
14933  {
14934  // note: at performs range check
14935  ptr = &ptr->at(reference_token);
14936  break;
14937  }
14938 
14940  {
14941  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14942  {
14943  // "-" always fails the range check
14945  "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
14946  ") is out of range"), ptr));
14947  }
14948 
14949  // note: at performs range check
14950  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14951  break;
14952  }
14953 
14954  case detail::value_t::null:
14962  default:
14963  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14964  }
14965  }
14966 
14967  return *ptr;
14968  }
14969 
14983  template<typename BasicJsonType>
14984  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
14985  {
14986  for (const auto& reference_token : reference_tokens)
14987  {
14988  switch (ptr->type())
14989  {
14991  {
14992  // use unchecked object access
14993  ptr = &ptr->operator[](reference_token);
14994  break;
14995  }
14996 
14998  {
14999  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
15000  {
15001  // "-" cannot be used for const access
15002  JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
15003  }
15004 
15005  // use unchecked array access
15006  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
15007  break;
15008  }
15009 
15010  case detail::value_t::null:
15018  default:
15019  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
15020  }
15021  }
15022 
15023  return *ptr;
15024  }
15025 
15032  template<typename BasicJsonType>
15033  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
15034  {
15035  for (const auto& reference_token : reference_tokens)
15036  {
15037  switch (ptr->type())
15038  {
15040  {
15041  // note: at performs range check
15042  ptr = &ptr->at(reference_token);
15043  break;
15044  }
15045 
15047  {
15048  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
15049  {
15050  // "-" always fails the range check
15052  "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
15053  ") is out of range"), ptr));
15054  }
15055 
15056  // note: at performs range check
15057  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
15058  break;
15059  }
15060 
15061  case detail::value_t::null:
15069  default:
15070  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
15071  }
15072  }
15073 
15074  return *ptr;
15075  }
15076 
15081  template<typename BasicJsonType>
15082  bool contains(const BasicJsonType* ptr) const
15083  {
15084  for (const auto& reference_token : reference_tokens)
15085  {
15086  switch (ptr->type())
15087  {
15089  {
15090  if (!ptr->contains(reference_token))
15091  {
15092  // we did not find the key in the object
15093  return false;
15094  }
15095 
15096  ptr = &ptr->operator[](reference_token);
15097  break;
15098  }
15099 
15101  {
15102  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
15103  {
15104  // "-" always fails the range check
15105  return false;
15106  }
15107  if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
15108  {
15109  // invalid char
15110  return false;
15111  }
15112  if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
15113  {
15114  if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
15115  {
15116  // first char should be between '1' and '9'
15117  return false;
15118  }
15119  for (std::size_t i = 1; i < reference_token.size(); i++)
15120  {
15121  if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
15122  {
15123  // other char should be between '0' and '9'
15124  return false;
15125  }
15126  }
15127  }
15128 
15129  const auto idx = array_index<BasicJsonType>(reference_token);
15130  if (idx >= ptr->size())
15131  {
15132  // index out of range
15133  return false;
15134  }
15135 
15136  ptr = &ptr->operator[](idx);
15137  break;
15138  }
15139 
15140  case detail::value_t::null:
15148  default:
15149  {
15150  // we do not expect primitive values if there is still a
15151  // reference token to process
15152  return false;
15153  }
15154  }
15155  }
15156 
15157  // no reference token left means we found a primitive value
15158  return true;
15159  }
15160 
15170  static std::vector<string_t> split(const string_t& reference_string)
15171  {
15172  std::vector<string_t> result;
15173 
15174  // special case: empty reference string -> no reference tokens
15175  if (reference_string.empty())
15176  {
15177  return result;
15178  }
15179 
15180  // check if nonempty reference string begins with slash
15181  if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
15182  {
15183  JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
15184  }
15185 
15186  // extract the reference tokens:
15187  // - slash: position of the last read slash (or end of string)
15188  // - start: position after the previous slash
15189  for (
15190  // search for the first slash after the first character
15191  std::size_t slash = reference_string.find_first_of('/', 1),
15192  // set the beginning of the first reference token
15193  start = 1;
15194  // we can stop if start == 0 (if slash == string_t::npos)
15195  start != 0;
15196  // set the beginning of the next reference token
15197  // (will eventually be 0 if slash == string_t::npos)
15198  start = (slash == string_t::npos) ? 0 : slash + 1,
15199  // find next slash
15200  slash = reference_string.find_first_of('/', start))
15201  {
15202  // use the text between the beginning of the reference token
15203  // (start) and the last slash (slash).
15204  auto reference_token = reference_string.substr(start, slash - start);
15205 
15206  // check reference tokens are properly escaped
15207  for (std::size_t pos = reference_token.find_first_of('~');
15208  pos != string_t::npos;
15209  pos = reference_token.find_first_of('~', pos + 1))
15210  {
15211  JSON_ASSERT(reference_token[pos] == '~');
15212 
15213  // ~ must be followed by 0 or 1
15214  if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
15215  (reference_token[pos + 1] != '0' &&
15216  reference_token[pos + 1] != '1')))
15217  {
15218  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
15219  }
15220  }
15221 
15222  // finally, store the reference token
15223  detail::unescape(reference_token);
15224  result.push_back(reference_token);
15225  }
15226 
15227  return result;
15228  }
15229 
15230  private:
15238  template<typename BasicJsonType>
15239  static void flatten(const string_t& reference_string,
15240  const BasicJsonType& value,
15241  BasicJsonType& result)
15242  {
15243  switch (value.type())
15244  {
15246  {
15247  if (value.m_data.m_value.array->empty())
15248  {
15249  // flatten empty array as null
15250  result[reference_string] = nullptr;
15251  }
15252  else
15253  {
15254  // iterate array and use index as reference string
15255  for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i)
15256  {
15257  flatten(detail::concat<string_t>(reference_string, '/', std::to_string(i)),
15258  value.m_data.m_value.array->operator[](i), result);
15259  }
15260  }
15261  break;
15262  }
15263 
15265  {
15266  if (value.m_data.m_value.object->empty())
15267  {
15268  // flatten empty object as null
15269  result[reference_string] = nullptr;
15270  }
15271  else
15272  {
15273  // iterate object and use keys as reference string
15274  for (const auto& element : *value.m_data.m_value.object)
15275  {
15276  flatten(detail::concat<string_t>(reference_string, '/', detail::escape(element.first)), element.second, result);
15277  }
15278  }
15279  break;
15280  }
15281 
15282  case detail::value_t::null:
15290  default:
15291  {
15292  // add primitive value with its reference string
15293  result[reference_string] = value;
15294  break;
15295  }
15296  }
15297  }
15298 
15309  template<typename BasicJsonType>
15310  static BasicJsonType
15311  unflatten(const BasicJsonType& value)
15312  {
15313  if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
15314  {
15315  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
15316  }
15317 
15318  BasicJsonType result;
15319 
15320  // iterate the JSON object values
15321  for (const auto& element : *value.m_data.m_value.object)
15322  {
15323  if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
15324  {
15325  JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
15326  }
15327 
15328  // assign value to reference pointed to by JSON pointer; Note that if
15329  // the JSON pointer is "" (i.e., points to the whole value), function
15330  // get_and_create returns a reference to result itself. An assignment
15331  // will then create a primitive value.
15332  json_pointer(element.first).get_and_create(result) = element.second;
15333  }
15334 
15335  return result;
15336  }
15337 
15338  // can't use conversion operator because of ambiguity
15339  json_pointer<string_t> convert() const&
15340  {
15341  json_pointer<string_t> result;
15342  result.reference_tokens = reference_tokens;
15343  return result;
15344  }
15345 
15346  json_pointer<string_t> convert()&&
15347  {
15348  json_pointer<string_t> result;
15349  result.reference_tokens = std::move(reference_tokens);
15350  return result;
15351  }
15352 
15353  public:
15354 #if JSON_HAS_THREE_WAY_COMPARISON
15357  template<typename RefStringTypeRhs>
15358  bool operator==(const json_pointer<RefStringTypeRhs>& rhs) const noexcept
15359  {
15360  return reference_tokens == rhs.reference_tokens;
15361  }
15362 
15365  JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer))
15366  bool operator==(const string_t& rhs) const
15367  {
15368  return *this == json_pointer(rhs);
15369  }
15370 
15372  template<typename RefStringTypeRhs>
15373  std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*
15374  {
15375  return reference_tokens <=> rhs.reference_tokens; // *NOPAD*
15376  }
15377 #else
15380  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
15381  // NOLINTNEXTLINE(readability-redundant-declaration)
15382  friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
15383  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
15384 
15387  template<typename RefStringTypeLhs, typename StringType>
15388  // NOLINTNEXTLINE(readability-redundant-declaration)
15389  friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
15390  const StringType& rhs);
15391 
15394  template<typename RefStringTypeRhs, typename StringType>
15395  // NOLINTNEXTLINE(readability-redundant-declaration)
15396  friend bool operator==(const StringType& lhs,
15397  const json_pointer<RefStringTypeRhs>& rhs);
15398 
15401  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
15402  // NOLINTNEXTLINE(readability-redundant-declaration)
15403  friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
15404  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
15405 
15408  template<typename RefStringTypeLhs, typename StringType>
15409  // NOLINTNEXTLINE(readability-redundant-declaration)
15410  friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
15411  const StringType& rhs);
15412 
15415  template<typename RefStringTypeRhs, typename StringType>
15416  // NOLINTNEXTLINE(readability-redundant-declaration)
15417  friend bool operator!=(const StringType& lhs,
15418  const json_pointer<RefStringTypeRhs>& rhs);
15419 
15421  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
15422  // NOLINTNEXTLINE(readability-redundant-declaration)
15423  friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
15424  const json_pointer<RefStringTypeRhs>& rhs) noexcept;
15425 #endif
15426 
15427  private:
15429  std::vector<string_t> reference_tokens;
15430 };
15431 
15432 #if !JSON_HAS_THREE_WAY_COMPARISON
15433 // functions cannot be defined inside class due to ODR violations
15434 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
15436  const json_pointer<RefStringTypeRhs>& rhs) noexcept
15437 {
15438  return lhs.reference_tokens == rhs.reference_tokens;
15439 }
15440 
15441 template<typename RefStringTypeLhs,
15442  typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
15444 inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
15445  const StringType& rhs)
15446 {
15447  return lhs == json_pointer<RefStringTypeLhs>(rhs);
15448 }
15449 
15450 template<typename RefStringTypeRhs,
15451  typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
15453 inline bool operator==(const StringType& lhs,
15454  const json_pointer<RefStringTypeRhs>& rhs)
15455 {
15456  return json_pointer<RefStringTypeRhs>(lhs) == rhs;
15457 }
15458 
15459 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
15461  const json_pointer<RefStringTypeRhs>& rhs) noexcept
15462 {
15463  return !(lhs == rhs);
15464 }
15465 
15466 template<typename RefStringTypeLhs,
15467  typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
15469 inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
15470  const StringType& rhs)
15471 {
15472  return !(lhs == rhs);
15473 }
15474 
15475 template<typename RefStringTypeRhs,
15476  typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
15478 inline bool operator!=(const StringType& lhs,
15479  const json_pointer<RefStringTypeRhs>& rhs)
15480 {
15481  return !(lhs == rhs);
15482 }
15483 
15484 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
15486  const json_pointer<RefStringTypeRhs>& rhs) noexcept
15487 {
15488  return lhs.reference_tokens < rhs.reference_tokens;
15489 }
15490 #endif
15491 
15493 
15494 // #include <nlohmann/detail/json_ref.hpp>
15495 // __ _____ _____ _____
15496 // __| | __| | | | JSON for Modern C++
15497 // | | |__ | | | | | | version 3.12.0
15498 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
15499 //
15500 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
15501 // SPDX-License-Identifier: MIT
15502 
15503 
15504 
15505 #include <initializer_list>
15506 #include <utility>
15507 
15508 // #include <nlohmann/detail/abi_macros.hpp>
15509 
15510 // #include <nlohmann/detail/meta/type_traits.hpp>
15511 
15512 
15514 namespace detail
15515 {
15516 
15517 template<typename BasicJsonType>
15519 {
15520  public:
15521  using value_type = BasicJsonType;
15522 
15524  : owned_value(std::move(value))
15525  {}
15526 
15527  json_ref(const value_type& value)
15528  : value_ref(&value)
15529  {}
15530 
15531  json_ref(std::initializer_list<json_ref> init)
15532  : owned_value(init)
15533  {}
15534 
15535  template <
15536  class... Args,
15537  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
15538  json_ref(Args && ... args)
15539  : owned_value(std::forward<Args>(args)...)
15540  {}
15541 
15542  // class should be movable only
15543  json_ref(json_ref&&) noexcept = default;
15544  json_ref(const json_ref&) = delete;
15545  json_ref& operator=(const json_ref&) = delete;
15546  json_ref& operator=(json_ref&&) = delete;
15547  ~json_ref() = default;
15548 
15549  value_type moved_or_copied() const
15550  {
15551  if (value_ref == nullptr)
15552  {
15553  return std::move(owned_value);
15554  }
15555  return *value_ref;
15556  }
15557 
15558  value_type const& operator*() const
15559  {
15560  return value_ref ? *value_ref : owned_value;
15561  }
15562 
15563  value_type const* operator->() const
15564  {
15565  return &** this;
15566  }
15567 
15568  private:
15569  mutable value_type owned_value = nullptr;
15570  value_type const* value_ref = nullptr;
15571 };
15572 
15573 } // namespace detail
15575 
15576 // #include <nlohmann/detail/macro_scope.hpp>
15577 
15578 // #include <nlohmann/detail/string_concat.hpp>
15579 
15580 // #include <nlohmann/detail/string_escape.hpp>
15581 
15582 // #include <nlohmann/detail/string_utils.hpp>
15583 
15584 // #include <nlohmann/detail/meta/cpp_future.hpp>
15585 
15586 // #include <nlohmann/detail/meta/type_traits.hpp>
15587 
15588 // #include <nlohmann/detail/output/binary_writer.hpp>
15589 // __ _____ _____ _____
15590 // __| | __| | | | JSON for Modern C++
15591 // | | |__ | | | | | | version 3.12.0
15592 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
15593 //
15594 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
15595 // SPDX-License-Identifier: MIT
15596 
15597 
15598 
15599 #include <algorithm> // reverse
15600 #include <array> // array
15601 #include <map> // map
15602 #include <cmath> // isnan, isinf
15603 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
15604 #include <cstring> // memcpy
15605 #include <limits> // numeric_limits
15606 #include <string> // string
15607 #include <utility> // move
15608 #include <vector> // vector
15609 
15610 // #include <nlohmann/detail/input/binary_reader.hpp>
15611 
15612 // #include <nlohmann/detail/macro_scope.hpp>
15613 
15614 // #include <nlohmann/detail/output/output_adapters.hpp>
15615 // __ _____ _____ _____
15616 // __| | __| | | | JSON for Modern C++
15617 // | | |__ | | | | | | version 3.12.0
15618 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
15619 //
15620 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
15621 // SPDX-License-Identifier: MIT
15622 
15623 
15624 
15625 #include <algorithm> // copy
15626 #include <cstddef> // size_t
15627 #include <iterator> // back_inserter
15628 #include <memory> // shared_ptr, make_shared
15629 #include <string> // basic_string
15630 #include <vector> // vector
15631 
15632 #ifndef JSON_NO_IO
15633  #include <ios> // streamsize
15634  #include <ostream> // basic_ostream
15635 #endif // JSON_NO_IO
15636 
15637 // #include <nlohmann/detail/macro_scope.hpp>
15638 
15639 
15641 namespace detail
15642 {
15643 
15645 template<typename CharType> struct output_adapter_protocol
15646 {
15647  virtual void write_character(CharType c) = 0;
15648  virtual void write_characters(const CharType* s, std::size_t length) = 0;
15649  virtual ~output_adapter_protocol() = default;
15650 
15654  output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
15655  output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
15656 };
15657 
15659 template<typename CharType>
15660 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
15661 
15663 template<typename CharType, typename AllocatorType = std::allocator<CharType>>
15665 {
15666  public:
15667  explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
15668  : v(vec)
15669  {}
15670 
15671  void write_character(CharType c) override
15672  {
15673  v.push_back(c);
15674  }
15675 
15677  void write_characters(const CharType* s, std::size_t length) override
15678  {
15679  v.insert(v.end(), s, s + length);
15680  }
15681 
15682  private:
15683  std::vector<CharType, AllocatorType>& v;
15684 };
15685 
15686 #ifndef JSON_NO_IO
15688 template<typename CharType>
15690 {
15691  public:
15692  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
15693  : stream(s)
15694  {}
15695 
15696  void write_character(CharType c) override
15697  {
15698  stream.put(c);
15699  }
15700 
15702  void write_characters(const CharType* s, std::size_t length) override
15703  {
15704  stream.write(s, static_cast<std::streamsize>(length));
15705  }
15706 
15707  private:
15708  std::basic_ostream<CharType>& stream;
15709 };
15710 #endif // JSON_NO_IO
15711 
15713 template<typename CharType, typename StringType = std::basic_string<CharType>>
15715 {
15716  public:
15717  explicit output_string_adapter(StringType& s) noexcept
15718  : str(s)
15719  {}
15720 
15721  void write_character(CharType c) override
15722  {
15723  str.push_back(c);
15724  }
15725 
15727  void write_characters(const CharType* s, std::size_t length) override
15728  {
15729  str.append(s, length);
15730  }
15731 
15732  private:
15733  StringType& str;
15734 };
15735 
15736 template<typename CharType, typename StringType = std::basic_string<CharType>>
15738 {
15739  public:
15740  template<typename AllocatorType = std::allocator<CharType>>
15741  output_adapter(std::vector<CharType, AllocatorType>& vec)
15742  : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
15743 
15744 #ifndef JSON_NO_IO
15745  output_adapter(std::basic_ostream<CharType>& s)
15746  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
15747 #endif // JSON_NO_IO
15748 
15749  output_adapter(StringType& s)
15750  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
15751 
15753  {
15754  return oa;
15755  }
15756 
15757  private:
15758  output_adapter_t<CharType> oa = nullptr;
15759 };
15760 
15761 } // namespace detail
15763 
15764 // #include <nlohmann/detail/string_concat.hpp>
15765 
15766 
15768 namespace detail
15769 {
15770 
15773 {
15774  draft2,
15775  draft3,
15776 };
15777 
15779 // binary writer //
15781 
15785 template<typename BasicJsonType, typename CharType>
15787 {
15788  using string_t = typename BasicJsonType::string_t;
15789  using binary_t = typename BasicJsonType::binary_t;
15790  using number_float_t = typename BasicJsonType::number_float_t;
15791 
15792  public:
15798  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
15799  {
15800  JSON_ASSERT(oa);
15801  }
15802 
15807  void write_bson(const BasicJsonType& j)
15808  {
15809  switch (j.type())
15810  {
15811  case value_t::object:
15812  {
15813  write_bson_object(*j.m_data.m_value.object);
15814  break;
15815  }
15816 
15817  case value_t::null:
15818  case value_t::array:
15819  case value_t::string:
15820  case value_t::boolean:
15821  case value_t::number_integer:
15822  case value_t::number_unsigned:
15823  case value_t::number_float:
15824  case value_t::binary:
15825  case value_t::discarded:
15826  default:
15827  {
15828  JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
15829  }
15830  }
15831  }
15832 
15836  void write_cbor(const BasicJsonType& j)
15837  {
15838  switch (j.type())
15839  {
15840  case value_t::null:
15841  {
15842  oa->write_character(to_char_type(0xF6));
15843  break;
15844  }
15845 
15846  case value_t::boolean:
15847  {
15848  oa->write_character(j.m_data.m_value.boolean
15849  ? to_char_type(0xF5)
15850  : to_char_type(0xF4));
15851  break;
15852  }
15853 
15854  case value_t::number_integer:
15855  {
15856  if (j.m_data.m_value.number_integer >= 0)
15857  {
15858  // CBOR does not differentiate between positive signed
15859  // integers and unsigned integers. Therefore, we used the
15860  // code from the value_t::number_unsigned case here.
15861  if (j.m_data.m_value.number_integer <= 0x17)
15862  {
15863  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15864  }
15865  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15866  {
15867  oa->write_character(to_char_type(0x18));
15868  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15869  }
15870  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
15871  {
15872  oa->write_character(to_char_type(0x19));
15873  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15874  }
15875  else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
15876  {
15877  oa->write_character(to_char_type(0x1A));
15878  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15879  }
15880  else
15881  {
15882  oa->write_character(to_char_type(0x1B));
15883  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15884  }
15885  }
15886  else
15887  {
15888  // The conversions below encode the sign in the first
15889  // byte, and the value is converted to a positive number.
15890  const auto positive_number = -1 - j.m_data.m_value.number_integer;
15891  if (j.m_data.m_value.number_integer >= -24)
15892  {
15893  write_number(static_cast<std::uint8_t>(0x20 + positive_number));
15894  }
15895  else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
15896  {
15897  oa->write_character(to_char_type(0x38));
15898  write_number(static_cast<std::uint8_t>(positive_number));
15899  }
15900  else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
15901  {
15902  oa->write_character(to_char_type(0x39));
15903  write_number(static_cast<std::uint16_t>(positive_number));
15904  }
15905  else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
15906  {
15907  oa->write_character(to_char_type(0x3A));
15908  write_number(static_cast<std::uint32_t>(positive_number));
15909  }
15910  else
15911  {
15912  oa->write_character(to_char_type(0x3B));
15913  write_number(static_cast<std::uint64_t>(positive_number));
15914  }
15915  }
15916  break;
15917  }
15918 
15919  case value_t::number_unsigned:
15920  {
15921  if (j.m_data.m_value.number_unsigned <= 0x17)
15922  {
15923  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
15924  }
15925  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15926  {
15927  oa->write_character(to_char_type(0x18));
15928  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
15929  }
15930  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15931  {
15932  oa->write_character(to_char_type(0x19));
15933  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));
15934  }
15935  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15936  {
15937  oa->write_character(to_char_type(0x1A));
15938  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));
15939  }
15940  else
15941  {
15942  oa->write_character(to_char_type(0x1B));
15943  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
15944  }
15945  break;
15946  }
15947 
15948  case value_t::number_float:
15949  {
15950  if (std::isnan(j.m_data.m_value.number_float))
15951  {
15952  // NaN is 0xf97e00 in CBOR
15953  oa->write_character(to_char_type(0xF9));
15954  oa->write_character(to_char_type(0x7E));
15955  oa->write_character(to_char_type(0x00));
15956  }
15957  else if (std::isinf(j.m_data.m_value.number_float))
15958  {
15959  // Infinity is 0xf97c00, -Infinity is 0xf9fc00
15960  oa->write_character(to_char_type(0xf9));
15961  oa->write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
15962  oa->write_character(to_char_type(0x00));
15963  }
15964  else
15965  {
15966  write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::cbor);
15967  }
15968  break;
15969  }
15970 
15971  case value_t::string:
15972  {
15973  // step 1: write control byte and the string length
15974  const auto N = j.m_data.m_value.string->size();
15975  if (N <= 0x17)
15976  {
15977  write_number(static_cast<std::uint8_t>(0x60 + N));
15978  }
15979  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15980  {
15981  oa->write_character(to_char_type(0x78));
15982  write_number(static_cast<std::uint8_t>(N));
15983  }
15984  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15985  {
15986  oa->write_character(to_char_type(0x79));
15987  write_number(static_cast<std::uint16_t>(N));
15988  }
15989  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15990  {
15991  oa->write_character(to_char_type(0x7A));
15992  write_number(static_cast<std::uint32_t>(N));
15993  }
15994  // LCOV_EXCL_START
15995  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15996  {
15997  oa->write_character(to_char_type(0x7B));
15998  write_number(static_cast<std::uint64_t>(N));
15999  }
16000  // LCOV_EXCL_STOP
16001 
16002  // step 2: write the string
16003  oa->write_characters(
16004  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
16005  j.m_data.m_value.string->size());
16006  break;
16007  }
16008 
16009  case value_t::array:
16010  {
16011  // step 1: write control byte and the array size
16012  const auto N = j.m_data.m_value.array->size();
16013  if (N <= 0x17)
16014  {
16015  write_number(static_cast<std::uint8_t>(0x80 + N));
16016  }
16017  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
16018  {
16019  oa->write_character(to_char_type(0x98));
16020  write_number(static_cast<std::uint8_t>(N));
16021  }
16022  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16023  {
16024  oa->write_character(to_char_type(0x99));
16025  write_number(static_cast<std::uint16_t>(N));
16026  }
16027  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16028  {
16029  oa->write_character(to_char_type(0x9A));
16030  write_number(static_cast<std::uint32_t>(N));
16031  }
16032  // LCOV_EXCL_START
16033  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
16034  {
16035  oa->write_character(to_char_type(0x9B));
16036  write_number(static_cast<std::uint64_t>(N));
16037  }
16038  // LCOV_EXCL_STOP
16039 
16040  // step 2: write each element
16041  for (const auto& el : *j.m_data.m_value.array)
16042  {
16043  write_cbor(el);
16044  }
16045  break;
16046  }
16047 
16048  case value_t::binary:
16049  {
16050  if (j.m_data.m_value.binary->has_subtype())
16051  {
16052  if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
16053  {
16054  write_number(static_cast<std::uint8_t>(0xd8));
16055  write_number(static_cast<std::uint8_t>(j.m_data.m_value.binary->subtype()));
16056  }
16057  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
16058  {
16059  write_number(static_cast<std::uint8_t>(0xd9));
16060  write_number(static_cast<std::uint16_t>(j.m_data.m_value.binary->subtype()));
16061  }
16062  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
16063  {
16064  write_number(static_cast<std::uint8_t>(0xda));
16065  write_number(static_cast<std::uint32_t>(j.m_data.m_value.binary->subtype()));
16066  }
16067  else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
16068  {
16069  write_number(static_cast<std::uint8_t>(0xdb));
16070  write_number(static_cast<std::uint64_t>(j.m_data.m_value.binary->subtype()));
16071  }
16072  }
16073 
16074  // step 1: write control byte and the binary array size
16075  const auto N = j.m_data.m_value.binary->size();
16076  if (N <= 0x17)
16077  {
16078  write_number(static_cast<std::uint8_t>(0x40 + N));
16079  }
16080  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
16081  {
16082  oa->write_character(to_char_type(0x58));
16083  write_number(static_cast<std::uint8_t>(N));
16084  }
16085  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16086  {
16087  oa->write_character(to_char_type(0x59));
16088  write_number(static_cast<std::uint16_t>(N));
16089  }
16090  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16091  {
16092  oa->write_character(to_char_type(0x5A));
16093  write_number(static_cast<std::uint32_t>(N));
16094  }
16095  // LCOV_EXCL_START
16096  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
16097  {
16098  oa->write_character(to_char_type(0x5B));
16099  write_number(static_cast<std::uint64_t>(N));
16100  }
16101  // LCOV_EXCL_STOP
16102 
16103  // step 2: write each element
16104  oa->write_characters(
16105  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
16106  N);
16107 
16108  break;
16109  }
16110 
16111  case value_t::object:
16112  {
16113  // step 1: write control byte and the object size
16114  const auto N = j.m_data.m_value.object->size();
16115  if (N <= 0x17)
16116  {
16117  write_number(static_cast<std::uint8_t>(0xA0 + N));
16118  }
16119  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
16120  {
16121  oa->write_character(to_char_type(0xB8));
16122  write_number(static_cast<std::uint8_t>(N));
16123  }
16124  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16125  {
16126  oa->write_character(to_char_type(0xB9));
16127  write_number(static_cast<std::uint16_t>(N));
16128  }
16129  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16130  {
16131  oa->write_character(to_char_type(0xBA));
16132  write_number(static_cast<std::uint32_t>(N));
16133  }
16134  // LCOV_EXCL_START
16135  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
16136  {
16137  oa->write_character(to_char_type(0xBB));
16138  write_number(static_cast<std::uint64_t>(N));
16139  }
16140  // LCOV_EXCL_STOP
16141 
16142  // step 2: write each element
16143  for (const auto& el : *j.m_data.m_value.object)
16144  {
16145  write_cbor(el.first);
16146  write_cbor(el.second);
16147  }
16148  break;
16149  }
16150 
16151  case value_t::discarded:
16152  default:
16153  break;
16154  }
16155  }
16156 
16160  void write_msgpack(const BasicJsonType& j)
16161  {
16162  switch (j.type())
16163  {
16164  case value_t::null: // nil
16165  {
16166  oa->write_character(to_char_type(0xC0));
16167  break;
16168  }
16169 
16170  case value_t::boolean: // true and false
16171  {
16172  oa->write_character(j.m_data.m_value.boolean
16173  ? to_char_type(0xC3)
16174  : to_char_type(0xC2));
16175  break;
16176  }
16177 
16178  case value_t::number_integer:
16179  {
16180  if (j.m_data.m_value.number_integer >= 0)
16181  {
16182  // MessagePack does not differentiate between positive
16183  // signed integers and unsigned integers. Therefore, we used
16184  // the code from the value_t::number_unsigned case here.
16185  if (j.m_data.m_value.number_unsigned < 128)
16186  {
16187  // positive fixnum
16188  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
16189  }
16190  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
16191  {
16192  // uint 8
16193  oa->write_character(to_char_type(0xCC));
16194  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
16195  }
16196  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
16197  {
16198  // uint 16
16199  oa->write_character(to_char_type(0xCD));
16200  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
16201  }
16202  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
16203  {
16204  // uint 32
16205  oa->write_character(to_char_type(0xCE));
16206  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
16207  }
16208  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
16209  {
16210  // uint 64
16211  oa->write_character(to_char_type(0xCF));
16212  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
16213  }
16214  }
16215  else
16216  {
16217  if (j.m_data.m_value.number_integer >= -32)
16218  {
16219  // negative fixnum
16220  write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
16221  }
16222  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
16223  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
16224  {
16225  // int 8
16226  oa->write_character(to_char_type(0xD0));
16227  write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
16228  }
16229  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
16230  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
16231  {
16232  // int 16
16233  oa->write_character(to_char_type(0xD1));
16234  write_number(static_cast<std::int16_t>(j.m_data.m_value.number_integer));
16235  }
16236  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
16237  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
16238  {
16239  // int 32
16240  oa->write_character(to_char_type(0xD2));
16241  write_number(static_cast<std::int32_t>(j.m_data.m_value.number_integer));
16242  }
16243  else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
16244  j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
16245  {
16246  // int 64
16247  oa->write_character(to_char_type(0xD3));
16248  write_number(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
16249  }
16250  }
16251  break;
16252  }
16253 
16254  case value_t::number_unsigned:
16255  {
16256  if (j.m_data.m_value.number_unsigned < 128)
16257  {
16258  // positive fixnum
16259  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
16260  }
16261  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
16262  {
16263  // uint 8
16264  oa->write_character(to_char_type(0xCC));
16265  write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
16266  }
16267  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
16268  {
16269  // uint 16
16270  oa->write_character(to_char_type(0xCD));
16271  write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
16272  }
16273  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
16274  {
16275  // uint 32
16276  oa->write_character(to_char_type(0xCE));
16277  write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
16278  }
16279  else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
16280  {
16281  // uint 64
16282  oa->write_character(to_char_type(0xCF));
16283  write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
16284  }
16285  break;
16286  }
16287 
16288  case value_t::number_float:
16289  {
16290  write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::msgpack);
16291  break;
16292  }
16293 
16294  case value_t::string:
16295  {
16296  // step 1: write control byte and the string length
16297  const auto N = j.m_data.m_value.string->size();
16298  if (N <= 31)
16299  {
16300  // fixstr
16301  write_number(static_cast<std::uint8_t>(0xA0 | N));
16302  }
16303  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
16304  {
16305  // str 8
16306  oa->write_character(to_char_type(0xD9));
16307  write_number(static_cast<std::uint8_t>(N));
16308  }
16309  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16310  {
16311  // str 16
16312  oa->write_character(to_char_type(0xDA));
16313  write_number(static_cast<std::uint16_t>(N));
16314  }
16315  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16316  {
16317  // str 32
16318  oa->write_character(to_char_type(0xDB));
16319  write_number(static_cast<std::uint32_t>(N));
16320  }
16321 
16322  // step 2: write the string
16323  oa->write_characters(
16324  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
16325  j.m_data.m_value.string->size());
16326  break;
16327  }
16328 
16329  case value_t::array:
16330  {
16331  // step 1: write control byte and the array size
16332  const auto N = j.m_data.m_value.array->size();
16333  if (N <= 15)
16334  {
16335  // fixarray
16336  write_number(static_cast<std::uint8_t>(0x90 | N));
16337  }
16338  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16339  {
16340  // array 16
16341  oa->write_character(to_char_type(0xDC));
16342  write_number(static_cast<std::uint16_t>(N));
16343  }
16344  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16345  {
16346  // array 32
16347  oa->write_character(to_char_type(0xDD));
16348  write_number(static_cast<std::uint32_t>(N));
16349  }
16350 
16351  // step 2: write each element
16352  for (const auto& el : *j.m_data.m_value.array)
16353  {
16354  write_msgpack(el);
16355  }
16356  break;
16357  }
16358 
16359  case value_t::binary:
16360  {
16361  // step 0: determine if the binary type has a set subtype to
16362  // determine whether to use the ext or fixext types
16363  const bool use_ext = j.m_data.m_value.binary->has_subtype();
16364 
16365  // step 1: write control byte and the byte string length
16366  const auto N = j.m_data.m_value.binary->size();
16367  if (N <= (std::numeric_limits<std::uint8_t>::max)())
16368  {
16369  std::uint8_t output_type{};
16370  bool fixed = true;
16371  if (use_ext)
16372  {
16373  switch (N)
16374  {
16375  case 1:
16376  output_type = 0xD4; // fixext 1
16377  break;
16378  case 2:
16379  output_type = 0xD5; // fixext 2
16380  break;
16381  case 4:
16382  output_type = 0xD6; // fixext 4
16383  break;
16384  case 8:
16385  output_type = 0xD7; // fixext 8
16386  break;
16387  case 16:
16388  output_type = 0xD8; // fixext 16
16389  break;
16390  default:
16391  output_type = 0xC7; // ext 8
16392  fixed = false;
16393  break;
16394  }
16395 
16396  }
16397  else
16398  {
16399  output_type = 0xC4; // bin 8
16400  fixed = false;
16401  }
16402 
16403  oa->write_character(to_char_type(output_type));
16404  if (!fixed)
16405  {
16406  write_number(static_cast<std::uint8_t>(N));
16407  }
16408  }
16409  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16410  {
16411  const std::uint8_t output_type = use_ext
16412  ? 0xC8 // ext 16
16413  : 0xC5; // bin 16
16414 
16415  oa->write_character(to_char_type(output_type));
16416  write_number(static_cast<std::uint16_t>(N));
16417  }
16418  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16419  {
16420  const std::uint8_t output_type = use_ext
16421  ? 0xC9 // ext 32
16422  : 0xC6; // bin 32
16423 
16424  oa->write_character(to_char_type(output_type));
16425  write_number(static_cast<std::uint32_t>(N));
16426  }
16427 
16428  // step 1.5: if this is an ext type, write the subtype
16429  if (use_ext)
16430  {
16431  write_number(static_cast<std::int8_t>(j.m_data.m_value.binary->subtype()));
16432  }
16433 
16434  // step 2: write the byte string
16435  oa->write_characters(
16436  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
16437  N);
16438 
16439  break;
16440  }
16441 
16442  case value_t::object:
16443  {
16444  // step 1: write control byte and the object size
16445  const auto N = j.m_data.m_value.object->size();
16446  if (N <= 15)
16447  {
16448  // fixmap
16449  write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
16450  }
16451  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
16452  {
16453  // map 16
16454  oa->write_character(to_char_type(0xDE));
16455  write_number(static_cast<std::uint16_t>(N));
16456  }
16457  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
16458  {
16459  // map 32
16460  oa->write_character(to_char_type(0xDF));
16461  write_number(static_cast<std::uint32_t>(N));
16462  }
16463 
16464  // step 2: write each element
16465  for (const auto& el : *j.m_data.m_value.object)
16466  {
16467  write_msgpack(el.first);
16468  write_msgpack(el.second);
16469  }
16470  break;
16471  }
16472 
16473  case value_t::discarded:
16474  default:
16475  break;
16476  }
16477  }
16478 
16487  void write_ubjson(const BasicJsonType& j, const bool use_count,
16488  const bool use_type, const bool add_prefix = true,
16489  const bool use_bjdata = false, const bjdata_version_t bjdata_version = bjdata_version_t::draft2)
16490  {
16491  const bool bjdata_draft3 = use_bjdata && bjdata_version == bjdata_version_t::draft3;
16492 
16493  switch (j.type())
16494  {
16495  case value_t::null:
16496  {
16497  if (add_prefix)
16498  {
16499  oa->write_character(to_char_type('Z'));
16500  }
16501  break;
16502  }
16503 
16504  case value_t::boolean:
16505  {
16506  if (add_prefix)
16507  {
16508  oa->write_character(j.m_data.m_value.boolean
16509  ? to_char_type('T')
16510  : to_char_type('F'));
16511  }
16512  break;
16513  }
16514 
16515  case value_t::number_integer:
16516  {
16517  write_number_with_ubjson_prefix(j.m_data.m_value.number_integer, add_prefix, use_bjdata);
16518  break;
16519  }
16520 
16521  case value_t::number_unsigned:
16522  {
16523  write_number_with_ubjson_prefix(j.m_data.m_value.number_unsigned, add_prefix, use_bjdata);
16524  break;
16525  }
16526 
16527  case value_t::number_float:
16528  {
16529  write_number_with_ubjson_prefix(j.m_data.m_value.number_float, add_prefix, use_bjdata);
16530  break;
16531  }
16532 
16533  case value_t::string:
16534  {
16535  if (add_prefix)
16536  {
16537  oa->write_character(to_char_type('S'));
16538  }
16539  write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
16540  oa->write_characters(
16541  reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
16542  j.m_data.m_value.string->size());
16543  break;
16544  }
16545 
16546  case value_t::array:
16547  {
16548  if (add_prefix)
16549  {
16550  oa->write_character(to_char_type('['));
16551  }
16552 
16553  bool prefix_required = true;
16554  if (use_type && !j.m_data.m_value.array->empty())
16555  {
16556  JSON_ASSERT(use_count);
16557  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
16558  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
16559  [this, first_prefix, use_bjdata](const BasicJsonType & v)
16560  {
16561  return ubjson_prefix(v, use_bjdata) == first_prefix;
16562  });
16563 
16564  std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
16565 
16566  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
16567  {
16568  prefix_required = false;
16569  oa->write_character(to_char_type('$'));
16570  oa->write_character(first_prefix);
16571  }
16572  }
16573 
16574  if (use_count)
16575  {
16576  oa->write_character(to_char_type('#'));
16577  write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
16578  }
16579 
16580  for (const auto& el : *j.m_data.m_value.array)
16581  {
16582  write_ubjson(el, use_count, use_type, prefix_required, use_bjdata, bjdata_version);
16583  }
16584 
16585  if (!use_count)
16586  {
16587  oa->write_character(to_char_type(']'));
16588  }
16589 
16590  break;
16591  }
16592 
16593  case value_t::binary:
16594  {
16595  if (add_prefix)
16596  {
16597  oa->write_character(to_char_type('['));
16598  }
16599 
16600  if (use_type && (bjdata_draft3 || !j.m_data.m_value.binary->empty()))
16601  {
16602  JSON_ASSERT(use_count);
16603  oa->write_character(to_char_type('$'));
16604  oa->write_character(bjdata_draft3 ? 'B' : 'U');
16605  }
16606 
16607  if (use_count)
16608  {
16609  oa->write_character(to_char_type('#'));
16610  write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(), true, use_bjdata);
16611  }
16612 
16613  if (use_type)
16614  {
16615  oa->write_characters(
16616  reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
16617  j.m_data.m_value.binary->size());
16618  }
16619  else
16620  {
16621  for (size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)
16622  {
16623  oa->write_character(to_char_type(bjdata_draft3 ? 'B' : 'U'));
16624  oa->write_character(j.m_data.m_value.binary->data()[i]);
16625  }
16626  }
16627 
16628  if (!use_count)
16629  {
16630  oa->write_character(to_char_type(']'));
16631  }
16632 
16633  break;
16634  }
16635 
16636  case value_t::object:
16637  {
16638  if (use_bjdata && j.m_data.m_value.object->size() == 3 && j.m_data.m_value.object->find("_ArrayType_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArraySize_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArrayData_") != j.m_data.m_value.object->end())
16639  {
16640  if (!write_bjdata_ndarray(*j.m_data.m_value.object, use_count, use_type, bjdata_version)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
16641  {
16642  break;
16643  }
16644  }
16645 
16646  if (add_prefix)
16647  {
16648  oa->write_character(to_char_type('{'));
16649  }
16650 
16651  bool prefix_required = true;
16652  if (use_type && !j.m_data.m_value.object->empty())
16653  {
16654  JSON_ASSERT(use_count);
16655  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
16656  const bool same_prefix = std::all_of(j.begin(), j.end(),
16657  [this, first_prefix, use_bjdata](const BasicJsonType & v)
16658  {
16659  return ubjson_prefix(v, use_bjdata) == first_prefix;
16660  });
16661 
16662  std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
16663 
16664  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
16665  {
16666  prefix_required = false;
16667  oa->write_character(to_char_type('$'));
16668  oa->write_character(first_prefix);
16669  }
16670  }
16671 
16672  if (use_count)
16673  {
16674  oa->write_character(to_char_type('#'));
16675  write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
16676  }
16677 
16678  for (const auto& el : *j.m_data.m_value.object)
16679  {
16680  write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
16681  oa->write_characters(
16682  reinterpret_cast<const CharType*>(el.first.c_str()),
16683  el.first.size());
16684  write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata, bjdata_version);
16685  }
16686 
16687  if (!use_count)
16688  {
16689  oa->write_character(to_char_type('}'));
16690  }
16691 
16692  break;
16693  }
16694 
16695  case value_t::discarded:
16696  default:
16697  break;
16698  }
16699  }
16700 
16701  private:
16703  // BSON //
16705 
16710  static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
16711  {
16712  const auto it = name.find(static_cast<typename string_t::value_type>(0));
16713  if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
16714  {
16715  JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
16716  static_cast<void>(j);
16717  }
16718 
16719  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
16720  }
16721 
16725  void write_bson_entry_header(const string_t& name,
16726  const std::uint8_t element_type)
16727  {
16728  oa->write_character(to_char_type(element_type)); // boolean
16729  oa->write_characters(
16730  reinterpret_cast<const CharType*>(name.c_str()),
16731  name.size() + 1u);
16732  }
16733 
16737  void write_bson_boolean(const string_t& name,
16738  const bool value)
16739  {
16740  write_bson_entry_header(name, 0x08);
16741  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
16742  }
16743 
16747  void write_bson_double(const string_t& name,
16748  const double value)
16749  {
16750  write_bson_entry_header(name, 0x01);
16751  write_number<double>(value, true);
16752  }
16753 
16757  static std::size_t calc_bson_string_size(const string_t& value)
16758  {
16759  return sizeof(std::int32_t) + value.size() + 1ul;
16760  }
16761 
16765  void write_bson_string(const string_t& name,
16766  const string_t& value)
16767  {
16768  write_bson_entry_header(name, 0x02);
16769 
16770  write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
16771  oa->write_characters(
16772  reinterpret_cast<const CharType*>(value.c_str()),
16773  value.size() + 1);
16774  }
16775 
16779  void write_bson_null(const string_t& name)
16780  {
16781  write_bson_entry_header(name, 0x0A);
16782  }
16783 
16787  static std::size_t calc_bson_integer_size(const std::int64_t value)
16788  {
16789  return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
16790  ? sizeof(std::int32_t)
16791  : sizeof(std::int64_t);
16792  }
16793 
16797  void write_bson_integer(const string_t& name,
16798  const std::int64_t value)
16799  {
16800  if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
16801  {
16802  write_bson_entry_header(name, 0x10); // int32
16803  write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
16804  }
16805  else
16806  {
16807  write_bson_entry_header(name, 0x12); // int64
16808  write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
16809  }
16810  }
16811 
16815  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
16816  {
16817  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16818  ? sizeof(std::int32_t)
16819  : sizeof(std::int64_t);
16820  }
16821 
16825  void write_bson_unsigned(const string_t& name,
16826  const BasicJsonType& j)
16827  {
16828  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16829  {
16830  write_bson_entry_header(name, 0x10 /* int32 */);
16831  write_number<std::int32_t>(static_cast<std::int32_t>(j.m_data.m_value.number_unsigned), true);
16832  }
16833  else if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16834  {
16835  write_bson_entry_header(name, 0x12 /* int64 */);
16836  write_number<std::int64_t>(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned), true);
16837  }
16838  else
16839  {
16840  write_bson_entry_header(name, 0x11 /* uint64 */);
16841  write_number<std::uint64_t>(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned), true);
16842  }
16843  }
16844 
16848  void write_bson_object_entry(const string_t& name,
16849  const typename BasicJsonType::object_t& value)
16850  {
16851  write_bson_entry_header(name, 0x03); // object
16852  write_bson_object(value);
16853  }
16854 
16858  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
16859  {
16860  std::size_t array_index = 0ul;
16861 
16862  const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
16863  {
16864  return result + calc_bson_element_size(std::to_string(array_index++), el);
16865  });
16866 
16867  return sizeof(std::int32_t) + embedded_document_size + 1ul;
16868  }
16869 
16873  static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
16874  {
16875  return sizeof(std::int32_t) + value.size() + 1ul;
16876  }
16877 
16881  void write_bson_array(const string_t& name,
16882  const typename BasicJsonType::array_t& value)
16883  {
16884  write_bson_entry_header(name, 0x04); // array
16885  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
16886 
16887  std::size_t array_index = 0ul;
16888 
16889  for (const auto& el : value)
16890  {
16891  write_bson_element(std::to_string(array_index++), el);
16892  }
16893 
16894  oa->write_character(to_char_type(0x00));
16895  }
16896 
16900  void write_bson_binary(const string_t& name,
16901  const binary_t& value)
16902  {
16903  write_bson_entry_header(name, 0x05);
16904 
16905  write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
16906  write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
16907 
16908  oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
16909  }
16910 
16915  static std::size_t calc_bson_element_size(const string_t& name,
16916  const BasicJsonType& j)
16917  {
16918  const auto header_size = calc_bson_entry_header_size(name, j);
16919  switch (j.type())
16920  {
16921  case value_t::object:
16922  return header_size + calc_bson_object_size(*j.m_data.m_value.object);
16923 
16924  case value_t::array:
16925  return header_size + calc_bson_array_size(*j.m_data.m_value.array);
16926 
16927  case value_t::binary:
16928  return header_size + calc_bson_binary_size(*j.m_data.m_value.binary);
16929 
16930  case value_t::boolean:
16931  return header_size + 1ul;
16932 
16933  case value_t::number_float:
16934  return header_size + 8ul;
16935 
16936  case value_t::number_integer:
16937  return header_size + calc_bson_integer_size(j.m_data.m_value.number_integer);
16938 
16939  case value_t::number_unsigned:
16940  return header_size + calc_bson_unsigned_size(j.m_data.m_value.number_unsigned);
16941 
16942  case value_t::string:
16943  return header_size + calc_bson_string_size(*j.m_data.m_value.string);
16944 
16945  case value_t::null:
16946  return header_size + 0ul;
16947 
16948  // LCOV_EXCL_START
16949  case value_t::discarded:
16950  default:
16951  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16952  return 0ul;
16953  // LCOV_EXCL_STOP
16954  }
16955  }
16956 
16963  void write_bson_element(const string_t& name,
16964  const BasicJsonType& j)
16965  {
16966  switch (j.type())
16967  {
16968  case value_t::object:
16969  return write_bson_object_entry(name, *j.m_data.m_value.object);
16970 
16971  case value_t::array:
16972  return write_bson_array(name, *j.m_data.m_value.array);
16973 
16974  case value_t::binary:
16975  return write_bson_binary(name, *j.m_data.m_value.binary);
16976 
16977  case value_t::boolean:
16978  return write_bson_boolean(name, j.m_data.m_value.boolean);
16979 
16980  case value_t::number_float:
16981  return write_bson_double(name, j.m_data.m_value.number_float);
16982 
16983  case value_t::number_integer:
16984  return write_bson_integer(name, j.m_data.m_value.number_integer);
16985 
16986  case value_t::number_unsigned:
16987  return write_bson_unsigned(name, j);
16988 
16989  case value_t::string:
16990  return write_bson_string(name, *j.m_data.m_value.string);
16991 
16992  case value_t::null:
16993  return write_bson_null(name);
16994 
16995  // LCOV_EXCL_START
16996  case value_t::discarded:
16997  default:
16998  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16999  return;
17000  // LCOV_EXCL_STOP
17001  }
17002  }
17003 
17010  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
17011  {
17012  const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
17013  [](size_t result, const typename BasicJsonType::object_t::value_type & el)
17014  {
17015  return result += calc_bson_element_size(el.first, el.second);
17016  });
17017 
17018  return sizeof(std::int32_t) + document_size + 1ul;
17019  }
17020 
17025  void write_bson_object(const typename BasicJsonType::object_t& value)
17026  {
17027  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
17028 
17029  for (const auto& el : value)
17030  {
17031  write_bson_element(el.first, el.second);
17032  }
17033 
17034  oa->write_character(to_char_type(0x00));
17035  }
17036 
17038  // CBOR //
17040 
17041  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
17042  {
17043  return to_char_type(0xFA); // Single-Precision Float
17044  }
17045 
17046  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
17047  {
17048  return to_char_type(0xFB); // Double-Precision Float
17049  }
17050 
17052  // MsgPack //
17054 
17055  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
17056  {
17057  return to_char_type(0xCA); // float 32
17058  }
17059 
17060  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
17061  {
17062  return to_char_type(0xCB); // float 64
17063  }
17064 
17066  // UBJSON //
17068 
17069  // UBJSON: write number (floating point)
17070  template<typename NumberType, typename std::enable_if<
17071  std::is_floating_point<NumberType>::value, int>::type = 0>
17072  void write_number_with_ubjson_prefix(const NumberType n,
17073  const bool add_prefix,
17074  const bool use_bjdata)
17075  {
17076  if (add_prefix)
17077  {
17078  oa->write_character(get_ubjson_float_prefix(n));
17079  }
17080  write_number(n, use_bjdata);
17081  }
17082 
17083  // UBJSON: write number (unsigned integer)
17084  template<typename NumberType, typename std::enable_if<
17085  std::is_unsigned<NumberType>::value, int>::type = 0>
17086  void write_number_with_ubjson_prefix(const NumberType n,
17087  const bool add_prefix,
17088  const bool use_bjdata)
17089  {
17090  if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
17091  {
17092  if (add_prefix)
17093  {
17094  oa->write_character(to_char_type('i')); // int8
17095  }
17096  write_number(static_cast<std::uint8_t>(n), use_bjdata);
17097  }
17098  else if (n <= (std::numeric_limits<std::uint8_t>::max)())
17099  {
17100  if (add_prefix)
17101  {
17102  oa->write_character(to_char_type('U')); // uint8
17103  }
17104  write_number(static_cast<std::uint8_t>(n), use_bjdata);
17105  }
17106  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
17107  {
17108  if (add_prefix)
17109  {
17110  oa->write_character(to_char_type('I')); // int16
17111  }
17112  write_number(static_cast<std::int16_t>(n), use_bjdata);
17113  }
17114  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
17115  {
17116  if (add_prefix)
17117  {
17118  oa->write_character(to_char_type('u')); // uint16 - bjdata only
17119  }
17120  write_number(static_cast<std::uint16_t>(n), use_bjdata);
17121  }
17122  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
17123  {
17124  if (add_prefix)
17125  {
17126  oa->write_character(to_char_type('l')); // int32
17127  }
17128  write_number(static_cast<std::int32_t>(n), use_bjdata);
17129  }
17130  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
17131  {
17132  if (add_prefix)
17133  {
17134  oa->write_character(to_char_type('m')); // uint32 - bjdata only
17135  }
17136  write_number(static_cast<std::uint32_t>(n), use_bjdata);
17137  }
17138  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
17139  {
17140  if (add_prefix)
17141  {
17142  oa->write_character(to_char_type('L')); // int64
17143  }
17144  write_number(static_cast<std::int64_t>(n), use_bjdata);
17145  }
17146  else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
17147  {
17148  if (add_prefix)
17149  {
17150  oa->write_character(to_char_type('M')); // uint64 - bjdata only
17151  }
17152  write_number(static_cast<std::uint64_t>(n), use_bjdata);
17153  }
17154  else
17155  {
17156  if (add_prefix)
17157  {
17158  oa->write_character(to_char_type('H')); // high-precision number
17159  }
17160 
17161  const auto number = BasicJsonType(n).dump();
17162  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
17163  for (std::size_t i = 0; i < number.size(); ++i)
17164  {
17165  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
17166  }
17167  }
17168  }
17169 
17170  // UBJSON: write number (signed integer)
17171  template < typename NumberType, typename std::enable_if <
17172  std::is_signed<NumberType>::value&&
17173  !std::is_floating_point<NumberType>::value, int >::type = 0 >
17174  void write_number_with_ubjson_prefix(const NumberType n,
17175  const bool add_prefix,
17176  const bool use_bjdata)
17177  {
17178  if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
17179  {
17180  if (add_prefix)
17181  {
17182  oa->write_character(to_char_type('i')); // int8
17183  }
17184  write_number(static_cast<std::int8_t>(n), use_bjdata);
17185  }
17186  else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
17187  {
17188  if (add_prefix)
17189  {
17190  oa->write_character(to_char_type('U')); // uint8
17191  }
17192  write_number(static_cast<std::uint8_t>(n), use_bjdata);
17193  }
17194  else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
17195  {
17196  if (add_prefix)
17197  {
17198  oa->write_character(to_char_type('I')); // int16
17199  }
17200  write_number(static_cast<std::int16_t>(n), use_bjdata);
17201  }
17202  else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
17203  {
17204  if (add_prefix)
17205  {
17206  oa->write_character(to_char_type('u')); // uint16 - bjdata only
17207  }
17208  write_number(static_cast<uint16_t>(n), use_bjdata);
17209  }
17210  else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
17211  {
17212  if (add_prefix)
17213  {
17214  oa->write_character(to_char_type('l')); // int32
17215  }
17216  write_number(static_cast<std::int32_t>(n), use_bjdata);
17217  }
17218  else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
17219  {
17220  if (add_prefix)
17221  {
17222  oa->write_character(to_char_type('m')); // uint32 - bjdata only
17223  }
17224  write_number(static_cast<uint32_t>(n), use_bjdata);
17225  }
17226  else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
17227  {
17228  if (add_prefix)
17229  {
17230  oa->write_character(to_char_type('L')); // int64
17231  }
17232  write_number(static_cast<std::int64_t>(n), use_bjdata);
17233  }
17234  // LCOV_EXCL_START
17235  else
17236  {
17237  if (add_prefix)
17238  {
17239  oa->write_character(to_char_type('H')); // high-precision number
17240  }
17241 
17242  const auto number = BasicJsonType(n).dump();
17243  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
17244  for (std::size_t i = 0; i < number.size(); ++i)
17245  {
17246  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
17247  }
17248  }
17249  // LCOV_EXCL_STOP
17250  }
17251 
17255  CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
17256  {
17257  switch (j.type())
17258  {
17259  case value_t::null:
17260  return 'Z';
17261 
17262  case value_t::boolean:
17263  return j.m_data.m_value.boolean ? 'T' : 'F';
17264 
17265  case value_t::number_integer:
17266  {
17267  if ((std::numeric_limits<std::int8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
17268  {
17269  return 'i';
17270  }
17271  if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
17272  {
17273  return 'U';
17274  }
17275  if ((std::numeric_limits<std::int16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
17276  {
17277  return 'I';
17278  }
17279  if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
17280  {
17281  return 'u';
17282  }
17283  if ((std::numeric_limits<std::int32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
17284  {
17285  return 'l';
17286  }
17287  if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
17288  {
17289  return 'm';
17290  }
17291  if ((std::numeric_limits<std::int64_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
17292  {
17293  return 'L';
17294  }
17295  // anything else is treated as high-precision number
17296  return 'H'; // LCOV_EXCL_LINE
17297  }
17298 
17299  case value_t::number_unsigned:
17300  {
17301  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
17302  {
17303  return 'i';
17304  }
17305  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
17306  {
17307  return 'U';
17308  }
17309  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
17310  {
17311  return 'I';
17312  }
17313  if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
17314  {
17315  return 'u';
17316  }
17317  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
17318  {
17319  return 'l';
17320  }
17321  if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
17322  {
17323  return 'm';
17324  }
17325  if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
17326  {
17327  return 'L';
17328  }
17329  if (use_bjdata && j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
17330  {
17331  return 'M';
17332  }
17333  // anything else is treated as high-precision number
17334  return 'H'; // LCOV_EXCL_LINE
17335  }
17336 
17337  case value_t::number_float:
17338  return get_ubjson_float_prefix(j.m_data.m_value.number_float);
17339 
17340  case value_t::string:
17341  return 'S';
17342 
17343  case value_t::array: // fallthrough
17344  case value_t::binary:
17345  return '[';
17346 
17347  case value_t::object:
17348  return '{';
17349 
17350  case value_t::discarded:
17351  default: // discarded values
17352  return 'N';
17353  }
17354  }
17355 
17356  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
17357  {
17358  return 'd'; // float 32
17359  }
17360 
17361  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
17362  {
17363  return 'D'; // float 64
17364  }
17365 
17369  bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type, const bjdata_version_t bjdata_version)
17370  {
17371  std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
17372  {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'},
17373  {"char", 'C'}, {"byte", 'B'}
17374  };
17375 
17376  string_t key = "_ArrayType_";
17377  auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
17378  if (it == bjdtype.end())
17379  {
17380  return true;
17381  }
17382  CharType dtype = it->second;
17383 
17384  key = "_ArraySize_";
17385  std::size_t len = (value.at(key).empty() ? 0 : 1);
17386  for (const auto& el : value.at(key))
17387  {
17388  len *= static_cast<std::size_t>(el.m_data.m_value.number_unsigned);
17389  }
17390 
17391  key = "_ArrayData_";
17392  if (value.at(key).size() != len)
17393  {
17394  return true;
17395  }
17396 
17397  oa->write_character('[');
17398  oa->write_character('$');
17399  oa->write_character(dtype);
17400  oa->write_character('#');
17401 
17402  key = "_ArraySize_";
17403  write_ubjson(value.at(key), use_count, use_type, true, true, bjdata_version);
17404 
17405  key = "_ArrayData_";
17406  if (dtype == 'U' || dtype == 'C' || dtype == 'B')
17407  {
17408  for (const auto& el : value.at(key))
17409  {
17410  write_number(static_cast<std::uint8_t>(el.m_data.m_value.number_unsigned), true);
17411  }
17412  }
17413  else if (dtype == 'i')
17414  {
17415  for (const auto& el : value.at(key))
17416  {
17417  write_number(static_cast<std::int8_t>(el.m_data.m_value.number_integer), true);
17418  }
17419  }
17420  else if (dtype == 'u')
17421  {
17422  for (const auto& el : value.at(key))
17423  {
17424  write_number(static_cast<std::uint16_t>(el.m_data.m_value.number_unsigned), true);
17425  }
17426  }
17427  else if (dtype == 'I')
17428  {
17429  for (const auto& el : value.at(key))
17430  {
17431  write_number(static_cast<std::int16_t>(el.m_data.m_value.number_integer), true);
17432  }
17433  }
17434  else if (dtype == 'm')
17435  {
17436  for (const auto& el : value.at(key))
17437  {
17438  write_number(static_cast<std::uint32_t>(el.m_data.m_value.number_unsigned), true);
17439  }
17440  }
17441  else if (dtype == 'l')
17442  {
17443  for (const auto& el : value.at(key))
17444  {
17445  write_number(static_cast<std::int32_t>(el.m_data.m_value.number_integer), true);
17446  }
17447  }
17448  else if (dtype == 'M')
17449  {
17450  for (const auto& el : value.at(key))
17451  {
17452  write_number(static_cast<std::uint64_t>(el.m_data.m_value.number_unsigned), true);
17453  }
17454  }
17455  else if (dtype == 'L')
17456  {
17457  for (const auto& el : value.at(key))
17458  {
17459  write_number(static_cast<std::int64_t>(el.m_data.m_value.number_integer), true);
17460  }
17461  }
17462  else if (dtype == 'd')
17463  {
17464  for (const auto& el : value.at(key))
17465  {
17466  write_number(static_cast<float>(el.m_data.m_value.number_float), true);
17467  }
17468  }
17469  else if (dtype == 'D')
17470  {
17471  for (const auto& el : value.at(key))
17472  {
17473  write_number(static_cast<double>(el.m_data.m_value.number_float), true);
17474  }
17475  }
17476  return false;
17477  }
17478 
17480  // Utility functions //
17482 
17483  /*
17484  @brief write a number to output input
17485  @param[in] n number of type @a NumberType
17486  @param[in] OutputIsLittleEndian Set to true if output data is
17487  required to be little endian
17488  @tparam NumberType the type of the number
17489 
17490  @note This function needs to respect the system's endianness, because bytes
17491  in CBOR, MessagePack, and UBJSON are stored in network order (big
17492  endian) and therefore need reordering on little endian systems.
17493  On the other hand, BSON and BJData use little endian and should reorder
17494  on big endian systems.
17495  */
17496  template<typename NumberType>
17497  void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
17498  {
17499  // step 1: write number to array of length NumberType
17500  std::array<CharType, sizeof(NumberType)> vec{};
17501  std::memcpy(vec.data(), &n, sizeof(NumberType));
17502 
17503  // step 2: write array to output (with possible reordering)
17504  if (is_little_endian != OutputIsLittleEndian)
17505  {
17506  // reverse byte order prior to conversion if necessary
17507  std::reverse(vec.begin(), vec.end());
17508  }
17509 
17510  oa->write_characters(vec.data(), sizeof(NumberType));
17511  }
17512 
17513  void write_compact_float(const number_float_t n, detail::input_format_t format)
17514  {
17515 #ifdef __GNUC__
17516 #pragma GCC diagnostic push
17517 #pragma GCC diagnostic ignored "-Wfloat-equal"
17518 #endif
17519  if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
17520  static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
17521  static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
17522  {
17523  oa->write_character(format == detail::input_format_t::cbor
17524  ? get_cbor_float_prefix(static_cast<float>(n))
17525  : get_msgpack_float_prefix(static_cast<float>(n)));
17526  write_number(static_cast<float>(n));
17527  }
17528  else
17529  {
17530  oa->write_character(format == detail::input_format_t::cbor
17531  ? get_cbor_float_prefix(n)
17532  : get_msgpack_float_prefix(n));
17533  write_number(n);
17534  }
17535 #ifdef __GNUC__
17536 #pragma GCC diagnostic pop
17537 #endif
17538  }
17539 
17540  public:
17541  // The following to_char_type functions are implement the conversion
17542  // between uint8_t and CharType. In case CharType is not unsigned,
17543  // such a conversion is required to allow values greater than 128.
17544  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
17545  template < typename C = CharType,
17546  enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
17547  static constexpr CharType to_char_type(std::uint8_t x) noexcept
17548  {
17549  return *reinterpret_cast<char*>(&x);
17550  }
17551 
17552  template < typename C = CharType,
17553  enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
17554  static CharType to_char_type(std::uint8_t x) noexcept
17555  {
17556  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
17557  static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
17558  CharType result;
17559  std::memcpy(&result, &x, sizeof(x));
17560  return result;
17561  }
17562 
17563  template<typename C = CharType,
17565  static constexpr CharType to_char_type(std::uint8_t x) noexcept
17566  {
17567  return x;
17568  }
17569 
17570  template < typename InputCharType, typename C = CharType,
17571  enable_if_t <
17572  std::is_signed<C>::value &&
17573  std::is_signed<char>::value &&
17574  std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
17575  > * = nullptr >
17576  static constexpr CharType to_char_type(InputCharType x) noexcept
17577  {
17578  return x;
17579  }
17580 
17581  private:
17583  const bool is_little_endian = little_endianness();
17584 
17586  output_adapter_t<CharType> oa = nullptr;
17587 };
17588 
17589 } // namespace detail
17591 
17592 // #include <nlohmann/detail/output/output_adapters.hpp>
17593 
17594 // #include <nlohmann/detail/output/serializer.hpp>
17595 // __ _____ _____ _____
17596 // __| | __| | | | JSON for Modern C++
17597 // | | |__ | | | | | | version 3.12.0
17598 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
17599 //
17600 // SPDX-FileCopyrightText: 2008 - 2009 Björn Hoehrmann <bjoern@hoehrmann.de>
17601 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
17602 // SPDX-License-Identifier: MIT
17603 
17604 
17605 
17606 #include <algorithm> // reverse, remove, fill, find, none_of
17607 #include <array> // array
17608 #include <clocale> // localeconv, lconv
17609 #include <cmath> // labs, isfinite, isnan, signbit
17610 #include <cstddef> // size_t, ptrdiff_t
17611 #include <cstdint> // uint8_t
17612 #include <cstdio> // snprintf
17613 #include <limits> // numeric_limits
17614 #include <string> // string, char_traits
17615 #include <iomanip> // setfill, setw
17616 #include <type_traits> // is_same
17617 #include <utility> // move
17618 
17619 // #include <nlohmann/detail/conversions/to_chars.hpp>
17620 // __ _____ _____ _____
17621 // __| | __| | | | JSON for Modern C++
17622 // | | |__ | | | | | | version 3.12.0
17623 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
17624 //
17625 // SPDX-FileCopyrightText: 2009 Florian Loitsch <https://florian.loitsch.com/>
17626 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
17627 // SPDX-License-Identifier: MIT
17628 
17629 
17630 
17631 #include <array> // array
17632 #include <cmath> // signbit, isfinite
17633 #include <cstdint> // intN_t, uintN_t
17634 #include <cstring> // memcpy, memmove
17635 #include <limits> // numeric_limits
17636 #include <type_traits> // conditional
17637 
17638 // #include <nlohmann/detail/macro_scope.hpp>
17639 
17640 
17642 namespace detail
17643 {
17644 
17664 namespace dtoa_impl
17665 {
17666 
17667 template<typename Target, typename Source>
17668 Target reinterpret_bits(const Source source)
17669 {
17670  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
17671 
17672  Target target;
17673  std::memcpy(&target, &source, sizeof(Source));
17674  return target;
17675 }
17676 
17677 struct diyfp // f * 2^e
17678 {
17679  static constexpr int kPrecision = 64; // = q
17680 
17681  std::uint64_t f = 0;
17682  int e = 0;
17683 
17684  constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
17685 
17690  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
17691  {
17692  JSON_ASSERT(x.e == y.e);
17693  JSON_ASSERT(x.f >= y.f);
17694 
17695  return {x.f - y.f, x.e};
17696  }
17697 
17702  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
17703  {
17704  static_assert(kPrecision == 64, "internal error");
17705 
17706  // Computes:
17707  // f = round((x.f * y.f) / 2^q)
17708  // e = x.e + y.e + q
17709 
17710  // Emulate the 64-bit * 64-bit multiplication:
17711  //
17712  // p = u * v
17713  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
17714  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
17715  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
17716  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
17717  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
17718  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
17719  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
17720  //
17721  // (Since Q might be larger than 2^32 - 1)
17722  //
17723  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
17724  //
17725  // (Q_hi + H does not overflow a 64-bit int)
17726  //
17727  // = p_lo + 2^64 p_hi
17728 
17729  const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
17730  const std::uint64_t u_hi = x.f >> 32u;
17731  const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
17732  const std::uint64_t v_hi = y.f >> 32u;
17733 
17734  const std::uint64_t p0 = u_lo * v_lo;
17735  const std::uint64_t p1 = u_lo * v_hi;
17736  const std::uint64_t p2 = u_hi * v_lo;
17737  const std::uint64_t p3 = u_hi * v_hi;
17738 
17739  const std::uint64_t p0_hi = p0 >> 32u;
17740  const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
17741  const std::uint64_t p1_hi = p1 >> 32u;
17742  const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
17743  const std::uint64_t p2_hi = p2 >> 32u;
17744 
17745  std::uint64_t Q = p0_hi + p1_lo + p2_lo;
17746 
17747  // The full product might now be computed as
17748  //
17749  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
17750  // p_lo = p0_lo + (Q << 32)
17751  //
17752  // But in this particular case here, the full p_lo is not required.
17753  // Effectively we only need to add the highest bit in p_lo to p_hi (and
17754  // Q_hi + 1 does not overflow).
17755 
17756  Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
17757 
17758  const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
17759 
17760  return {h, x.e + y.e + 64};
17761  }
17762 
17767  static diyfp normalize(diyfp x) noexcept
17768  {
17769  JSON_ASSERT(x.f != 0);
17770 
17771  while ((x.f >> 63u) == 0)
17772  {
17773  x.f <<= 1u;
17774  x.e--;
17775  }
17776 
17777  return x;
17778  }
17779 
17784  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
17785  {
17786  const int delta = x.e - target_exponent;
17787 
17788  JSON_ASSERT(delta >= 0);
17789  JSON_ASSERT(((x.f << delta) >> delta) == x.f);
17790 
17791  return {x.f << delta, target_exponent};
17792  }
17793 };
17794 
17796 {
17800 };
17801 
17808 template<typename FloatType>
17810 {
17811  JSON_ASSERT(std::isfinite(value));
17812  JSON_ASSERT(value > 0);
17813 
17814  // Convert the IEEE representation into a diyfp.
17815  //
17816  // If v is denormal:
17817  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
17818  // If v is normalized:
17819  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
17820 
17821  static_assert(std::numeric_limits<FloatType>::is_iec559,
17822  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
17823 
17824  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
17825  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
17826  constexpr int kMinExp = 1 - kBias;
17827  constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
17828 
17829  using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
17830 
17831  const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
17832  const std::uint64_t E = bits >> (kPrecision - 1);
17833  const std::uint64_t F = bits & (kHiddenBit - 1);
17834 
17835  const bool is_denormal = E == 0;
17836  const diyfp v = is_denormal
17837  ? diyfp(F, kMinExp)
17838  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
17839 
17840  // Compute the boundaries m- and m+ of the floating-point value
17841  // v = f * 2^e.
17842  //
17843  // Determine v- and v+, the floating-point predecessor and successor if v,
17844  // respectively.
17845  //
17846  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
17847  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
17848  //
17849  // v+ = v + 2^e
17850  //
17851  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
17852  // between m- and m+ round to v, regardless of how the input rounding
17853  // algorithm breaks ties.
17854  //
17855  // ---+-------------+-------------+-------------+-------------+--- (A)
17856  // v- m- v m+ v+
17857  //
17858  // -----------------+------+------+-------------+-------------+--- (B)
17859  // v- m- v m+ v+
17860 
17861  const bool lower_boundary_is_closer = F == 0 && E > 1;
17862  const diyfp m_plus = diyfp((2 * v.f) + 1, v.e - 1);
17863  const diyfp m_minus = lower_boundary_is_closer
17864  ? diyfp((4 * v.f) - 1, v.e - 2) // (B)
17865  : diyfp((2 * v.f) - 1, v.e - 1); // (A)
17866 
17867  // Determine the normalized w+ = m+.
17868  const diyfp w_plus = diyfp::normalize(m_plus);
17869 
17870  // Determine w- = m- such that e_(w-) = e_(w+).
17871  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
17872 
17873  return {diyfp::normalize(v), w_minus, w_plus};
17874 }
17875 
17876 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
17877 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
17878 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
17879 //
17880 // alpha <= e = e_c + e_w + q <= gamma
17881 //
17882 // or
17883 //
17884 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
17885 // <= f_c * f_w * 2^gamma
17886 //
17887 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
17888 //
17889 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
17890 //
17891 // or
17892 //
17893 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
17894 //
17895 // The choice of (alpha,gamma) determines the size of the table and the form of
17896 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
17897 // in practice:
17898 //
17899 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
17900 // processed independently: An integral part p1, and a fractional part p2:
17901 //
17902 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
17903 // = (f div 2^-e) + (f mod 2^-e) * 2^e
17904 // = p1 + p2 * 2^e
17905 //
17906 // The conversion of p1 into decimal form requires a series of divisions and
17907 // modulos by (a power of) 10. These operations are faster for 32-bit than for
17908 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
17909 // achieved by choosing
17910 //
17911 // -e >= 32 or e <= -32 := gamma
17912 //
17913 // In order to convert the fractional part
17914 //
17915 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
17916 //
17917 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
17918 // d[-i] are extracted in order:
17919 //
17920 // (10 * p2) div 2^-e = d[-1]
17921 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
17922 //
17923 // The multiplication by 10 must not overflow. It is sufficient to choose
17924 //
17925 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
17926 //
17927 // Since p2 = f mod 2^-e < 2^-e,
17928 //
17929 // -e <= 60 or e >= -60 := alpha
17930 
17931 constexpr int kAlpha = -60;
17932 constexpr int kGamma = -32;
17933 
17934 struct cached_power // c = f * 2^e ~= 10^k
17935 {
17936  std::uint64_t f;
17937  int e;
17938  int k;
17939 };
17940 
17949 {
17950  // Now
17951  //
17952  // alpha <= e_c + e + q <= gamma (1)
17953  // ==> f_c * 2^alpha <= c * 2^e * 2^q
17954  //
17955  // and since the c's are normalized, 2^(q-1) <= f_c,
17956  //
17957  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
17958  // ==> 2^(alpha - e - 1) <= c
17959  //
17960  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
17961  //
17962  // k = ceil( log_10( 2^(alpha - e - 1) ) )
17963  // = ceil( (alpha - e - 1) * log_10(2) )
17964  //
17965  // From the paper:
17966  // "In theory the result of the procedure could be wrong since c is rounded,
17967  // and the computation itself is approximated [...]. In practice, however,
17968  // this simple function is sufficient."
17969  //
17970  // For IEEE double precision floating-point numbers converted into
17971  // normalized diyfp's w = f * 2^e, with q = 64,
17972  //
17973  // e >= -1022 (min IEEE exponent)
17974  // -52 (p - 1)
17975  // -52 (p - 1, possibly normalize denormal IEEE numbers)
17976  // -11 (normalize the diyfp)
17977  // = -1137
17978  //
17979  // and
17980  //
17981  // e <= +1023 (max IEEE exponent)
17982  // -52 (p - 1)
17983  // -11 (normalize the diyfp)
17984  // = 960
17985  //
17986  // This binary exponent range [-1137,960] results in a decimal exponent
17987  // range [-307,324]. One does not need to store a cached power for each
17988  // k in this range. For each such k it suffices to find a cached power
17989  // such that the exponent of the product lies in [alpha,gamma].
17990  // This implies that the difference of the decimal exponents of adjacent
17991  // table entries must be less than or equal to
17992  //
17993  // floor( (gamma - alpha) * log_10(2) ) = 8.
17994  //
17995  // (A smaller distance gamma-alpha would require a larger table.)
17996 
17997  // NB:
17998  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
17999 
18000  constexpr int kCachedPowersMinDecExp = -300;
18001  constexpr int kCachedPowersDecStep = 8;
18002 
18003  static constexpr std::array<cached_power, 79> kCachedPowers =
18004  {
18005  {
18006  { 0xAB70FE17C79AC6CA, -1060, -300 },
18007  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
18008  { 0xBE5691EF416BD60C, -1007, -284 },
18009  { 0x8DD01FAD907FFC3C, -980, -276 },
18010  { 0xD3515C2831559A83, -954, -268 },
18011  { 0x9D71AC8FADA6C9B5, -927, -260 },
18012  { 0xEA9C227723EE8BCB, -901, -252 },
18013  { 0xAECC49914078536D, -874, -244 },
18014  { 0x823C12795DB6CE57, -847, -236 },
18015  { 0xC21094364DFB5637, -821, -228 },
18016  { 0x9096EA6F3848984F, -794, -220 },
18017  { 0xD77485CB25823AC7, -768, -212 },
18018  { 0xA086CFCD97BF97F4, -741, -204 },
18019  { 0xEF340A98172AACE5, -715, -196 },
18020  { 0xB23867FB2A35B28E, -688, -188 },
18021  { 0x84C8D4DFD2C63F3B, -661, -180 },
18022  { 0xC5DD44271AD3CDBA, -635, -172 },
18023  { 0x936B9FCEBB25C996, -608, -164 },
18024  { 0xDBAC6C247D62A584, -582, -156 },
18025  { 0xA3AB66580D5FDAF6, -555, -148 },
18026  { 0xF3E2F893DEC3F126, -529, -140 },
18027  { 0xB5B5ADA8AAFF80B8, -502, -132 },
18028  { 0x87625F056C7C4A8B, -475, -124 },
18029  { 0xC9BCFF6034C13053, -449, -116 },
18030  { 0x964E858C91BA2655, -422, -108 },
18031  { 0xDFF9772470297EBD, -396, -100 },
18032  { 0xA6DFBD9FB8E5B88F, -369, -92 },
18033  { 0xF8A95FCF88747D94, -343, -84 },
18034  { 0xB94470938FA89BCF, -316, -76 },
18035  { 0x8A08F0F8BF0F156B, -289, -68 },
18036  { 0xCDB02555653131B6, -263, -60 },
18037  { 0x993FE2C6D07B7FAC, -236, -52 },
18038  { 0xE45C10C42A2B3B06, -210, -44 },
18039  { 0xAA242499697392D3, -183, -36 },
18040  { 0xFD87B5F28300CA0E, -157, -28 },
18041  { 0xBCE5086492111AEB, -130, -20 },
18042  { 0x8CBCCC096F5088CC, -103, -12 },
18043  { 0xD1B71758E219652C, -77, -4 },
18044  { 0x9C40000000000000, -50, 4 },
18045  { 0xE8D4A51000000000, -24, 12 },
18046  { 0xAD78EBC5AC620000, 3, 20 },
18047  { 0x813F3978F8940984, 30, 28 },
18048  { 0xC097CE7BC90715B3, 56, 36 },
18049  { 0x8F7E32CE7BEA5C70, 83, 44 },
18050  { 0xD5D238A4ABE98068, 109, 52 },
18051  { 0x9F4F2726179A2245, 136, 60 },
18052  { 0xED63A231D4C4FB27, 162, 68 },
18053  { 0xB0DE65388CC8ADA8, 189, 76 },
18054  { 0x83C7088E1AAB65DB, 216, 84 },
18055  { 0xC45D1DF942711D9A, 242, 92 },
18056  { 0x924D692CA61BE758, 269, 100 },
18057  { 0xDA01EE641A708DEA, 295, 108 },
18058  { 0xA26DA3999AEF774A, 322, 116 },
18059  { 0xF209787BB47D6B85, 348, 124 },
18060  { 0xB454E4A179DD1877, 375, 132 },
18061  { 0x865B86925B9BC5C2, 402, 140 },
18062  { 0xC83553C5C8965D3D, 428, 148 },
18063  { 0x952AB45CFA97A0B3, 455, 156 },
18064  { 0xDE469FBD99A05FE3, 481, 164 },
18065  { 0xA59BC234DB398C25, 508, 172 },
18066  { 0xF6C69A72A3989F5C, 534, 180 },
18067  { 0xB7DCBF5354E9BECE, 561, 188 },
18068  { 0x88FCF317F22241E2, 588, 196 },
18069  { 0xCC20CE9BD35C78A5, 614, 204 },
18070  { 0x98165AF37B2153DF, 641, 212 },
18071  { 0xE2A0B5DC971F303A, 667, 220 },
18072  { 0xA8D9D1535CE3B396, 694, 228 },
18073  { 0xFB9B7CD9A4A7443C, 720, 236 },
18074  { 0xBB764C4CA7A44410, 747, 244 },
18075  { 0x8BAB8EEFB6409C1A, 774, 252 },
18076  { 0xD01FEF10A657842C, 800, 260 },
18077  { 0x9B10A4E5E9913129, 827, 268 },
18078  { 0xE7109BFBA19C0C9D, 853, 276 },
18079  { 0xAC2820D9623BF429, 880, 284 },
18080  { 0x80444B5E7AA7CF85, 907, 292 },
18081  { 0xBF21E44003ACDD2D, 933, 300 },
18082  { 0x8E679C2F5E44FF8F, 960, 308 },
18083  { 0xD433179D9C8CB841, 986, 316 },
18084  { 0x9E19DB92B4E31BA9, 1013, 324 },
18085  }
18086  };
18087 
18088  // This computation gives exactly the same results for k as
18089  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
18090  // for |e| <= 1500, but doesn't require floating-point operations.
18091  // NB: log_10(2) ~= 78913 / 2^18
18092  JSON_ASSERT(e >= -1500);
18093  JSON_ASSERT(e <= 1500);
18094  const int f = kAlpha - e - 1;
18095  const int k = ((f * 78913) / (1 << 18)) + static_cast<int>(f > 0);
18096 
18097  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
18098  JSON_ASSERT(index >= 0);
18099  JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
18100 
18101  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
18102  JSON_ASSERT(kAlpha <= cached.e + e + 64);
18103  JSON_ASSERT(kGamma >= cached.e + e + 64);
18104 
18105  return cached;
18106 }
18107 
18112 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
18113 {
18114  // LCOV_EXCL_START
18115  if (n >= 1000000000)
18116  {
18117  pow10 = 1000000000;
18118  return 10;
18119  }
18120  // LCOV_EXCL_STOP
18121  if (n >= 100000000)
18122  {
18123  pow10 = 100000000;
18124  return 9;
18125  }
18126  if (n >= 10000000)
18127  {
18128  pow10 = 10000000;
18129  return 8;
18130  }
18131  if (n >= 1000000)
18132  {
18133  pow10 = 1000000;
18134  return 7;
18135  }
18136  if (n >= 100000)
18137  {
18138  pow10 = 100000;
18139  return 6;
18140  }
18141  if (n >= 10000)
18142  {
18143  pow10 = 10000;
18144  return 5;
18145  }
18146  if (n >= 1000)
18147  {
18148  pow10 = 1000;
18149  return 4;
18150  }
18151  if (n >= 100)
18152  {
18153  pow10 = 100;
18154  return 3;
18155  }
18156  if (n >= 10)
18157  {
18158  pow10 = 10;
18159  return 2;
18160  }
18161 
18162  pow10 = 1;
18163  return 1;
18164 }
18165 
18166 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
18167  std::uint64_t rest, std::uint64_t ten_k)
18168 {
18169  JSON_ASSERT(len >= 1);
18170  JSON_ASSERT(dist <= delta);
18171  JSON_ASSERT(rest <= delta);
18172  JSON_ASSERT(ten_k > 0);
18173 
18174  // <--------------------------- delta ---->
18175  // <---- dist --------->
18176  // --------------[------------------+-------------------]--------------
18177  // M- w M+
18178  //
18179  // ten_k
18180  // <------>
18181  // <---- rest ---->
18182  // --------------[------------------+----+--------------]--------------
18183  // w V
18184  // = buf * 10^k
18185  //
18186  // ten_k represents a unit-in-the-last-place in the decimal representation
18187  // stored in buf.
18188  // Decrement buf by ten_k while this takes buf closer to w.
18189 
18190  // The tests are written in this order to avoid overflow in unsigned
18191  // integer arithmetic.
18192 
18193  while (rest < dist
18194  && delta - rest >= ten_k
18195  && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
18196  {
18197  JSON_ASSERT(buf[len - 1] != '0');
18198  buf[len - 1]--;
18199  rest += ten_k;
18200  }
18201 }
18202 
18207 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
18208  diyfp M_minus, diyfp w, diyfp M_plus)
18209 {
18210  static_assert(kAlpha >= -60, "internal error");
18211  static_assert(kGamma <= -32, "internal error");
18212 
18213  // Generates the digits (and the exponent) of a decimal floating-point
18214  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
18215  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
18216  //
18217  // <--------------------------- delta ---->
18218  // <---- dist --------->
18219  // --------------[------------------+-------------------]--------------
18220  // M- w M+
18221  //
18222  // Grisu2 generates the digits of M+ from left to right and stops as soon as
18223  // V is in [M-,M+].
18224 
18225  JSON_ASSERT(M_plus.e >= kAlpha);
18226  JSON_ASSERT(M_plus.e <= kGamma);
18227 
18228  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
18229  std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
18230 
18231  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
18232  //
18233  // M+ = f * 2^e
18234  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
18235  // = ((p1 ) * 2^-e + (p2 )) * 2^e
18236  // = p1 + p2 * 2^e
18237 
18238  const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
18239 
18240  auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
18241  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
18242 
18243  // 1)
18244  //
18245  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
18246 
18247  JSON_ASSERT(p1 > 0);
18248 
18249  std::uint32_t pow10{};
18250  const int k = find_largest_pow10(p1, pow10);
18251 
18252  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
18253  //
18254  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
18255  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
18256  //
18257  // M+ = p1 + p2 * 2^e
18258  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
18259  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
18260  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
18261  //
18262  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
18263  //
18264  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
18265  //
18266  // but stop as soon as
18267  //
18268  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
18269 
18270  int n = k;
18271  while (n > 0)
18272  {
18273  // Invariants:
18274  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
18275  // pow10 = 10^(n-1) <= p1 < 10^n
18276  //
18277  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
18278  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
18279  //
18280  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
18281  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
18282  //
18283  JSON_ASSERT(d <= 9);
18284  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
18285  //
18286  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
18287  //
18288  p1 = r;
18289  n--;
18290  //
18291  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
18292  // pow10 = 10^n
18293  //
18294 
18295  // Now check if enough digits have been generated.
18296  // Compute
18297  //
18298  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
18299  //
18300  // Note:
18301  // Since rest and delta share the same exponent e, it suffices to
18302  // compare the significands.
18303  const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
18304  if (rest <= delta)
18305  {
18306  // V = buffer * 10^n, with M- <= V <= M+.
18307 
18308  decimal_exponent += n;
18309 
18310  // We may now just stop. But instead look if the buffer could be
18311  // decremented to bring V closer to w.
18312  //
18313  // pow10 = 10^n is now 1 ulp in the decimal representation V.
18314  // The rounding procedure works with diyfp's with an implicit
18315  // exponent of e.
18316  //
18317  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
18318  //
18319  const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
18320  grisu2_round(buffer, length, dist, delta, rest, ten_n);
18321 
18322  return;
18323  }
18324 
18325  pow10 /= 10;
18326  //
18327  // pow10 = 10^(n-1) <= p1 < 10^n
18328  // Invariants restored.
18329  }
18330 
18331  // 2)
18332  //
18333  // The digits of the integral part have been generated:
18334  //
18335  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
18336  // = buffer + p2 * 2^e
18337  //
18338  // Now generate the digits of the fractional part p2 * 2^e.
18339  //
18340  // Note:
18341  // No decimal point is generated: the exponent is adjusted instead.
18342  //
18343  // p2 actually represents the fraction
18344  //
18345  // p2 * 2^e
18346  // = p2 / 2^-e
18347  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
18348  //
18349  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
18350  //
18351  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
18352  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
18353  //
18354  // using
18355  //
18356  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
18357  // = ( d) * 2^-e + ( r)
18358  //
18359  // or
18360  // 10^m * p2 * 2^e = d + r * 2^e
18361  //
18362  // i.e.
18363  //
18364  // M+ = buffer + p2 * 2^e
18365  // = buffer + 10^-m * (d + r * 2^e)
18366  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
18367  //
18368  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
18369 
18370  JSON_ASSERT(p2 > delta);
18371 
18372  int m = 0;
18373  for (;;)
18374  {
18375  // Invariant:
18376  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
18377  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
18378  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
18379  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
18380  //
18381  JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
18382  p2 *= 10;
18383  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
18384  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
18385  //
18386  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
18387  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
18388  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
18389  //
18390  JSON_ASSERT(d <= 9);
18391  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
18392  //
18393  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
18394  //
18395  p2 = r;
18396  m++;
18397  //
18398  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
18399  // Invariant restored.
18400 
18401  // Check if enough digits have been generated.
18402  //
18403  // 10^-m * p2 * 2^e <= delta * 2^e
18404  // p2 * 2^e <= 10^m * delta * 2^e
18405  // p2 <= 10^m * delta
18406  delta *= 10;
18407  dist *= 10;
18408  if (p2 <= delta)
18409  {
18410  break;
18411  }
18412  }
18413 
18414  // V = buffer * 10^-m, with M- <= V <= M+.
18415 
18416  decimal_exponent -= m;
18417 
18418  // 1 ulp in the decimal representation is now 10^-m.
18419  // Since delta and dist are now scaled by 10^m, we need to do the
18420  // same with ulp in order to keep the units in sync.
18421  //
18422  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
18423  //
18424  const std::uint64_t ten_m = one.f;
18425  grisu2_round(buffer, length, dist, delta, p2, ten_m);
18426 
18427  // By construction this algorithm generates the shortest possible decimal
18428  // number (Loitsch, Theorem 6.2) which rounds back to w.
18429  // For an input number of precision p, at least
18430  //
18431  // N = 1 + ceil(p * log_10(2))
18432  //
18433  // decimal digits are sufficient to identify all binary floating-point
18434  // numbers (Matula, "In-and-Out conversions").
18435  // This implies that the algorithm does not produce more than N decimal
18436  // digits.
18437  //
18438  // N = 17 for p = 53 (IEEE double precision)
18439  // N = 9 for p = 24 (IEEE single precision)
18440 }
18441 
18448 inline void grisu2(char* buf, int& len, int& decimal_exponent,
18449  diyfp m_minus, diyfp v, diyfp m_plus)
18450 {
18451  JSON_ASSERT(m_plus.e == m_minus.e);
18452  JSON_ASSERT(m_plus.e == v.e);
18453 
18454  // --------(-----------------------+-----------------------)-------- (A)
18455  // m- v m+
18456  //
18457  // --------------------(-----------+-----------------------)-------- (B)
18458  // m- v m+
18459  //
18460  // First scale v (and m- and m+) such that the exponent is in the range
18461  // [alpha, gamma].
18462 
18463  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
18464 
18465  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
18466 
18467  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
18468  const diyfp w = diyfp::mul(v, c_minus_k);
18469  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
18470  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
18471 
18472  // ----(---+---)---------------(---+---)---------------(---+---)----
18473  // w- w w+
18474  // = c*m- = c*v = c*m+
18475  //
18476  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
18477  // w+ are now off by a small amount.
18478  // In fact:
18479  //
18480  // w - v * 10^k < 1 ulp
18481  //
18482  // To account for this inaccuracy, add resp. subtract 1 ulp.
18483  //
18484  // --------+---[---------------(---+---)---------------]---+--------
18485  // w- M- w M+ w+
18486  //
18487  // Now any number in [M-, M+] (bounds included) will round to w when input,
18488  // regardless of how the input rounding algorithm breaks ties.
18489  //
18490  // And digit_gen generates the shortest possible such number in [M-, M+].
18491  // Note that this does not mean that Grisu2 always generates the shortest
18492  // possible number in the interval (m-, m+).
18493  const diyfp M_minus(w_minus.f + 1, w_minus.e);
18494  const diyfp M_plus (w_plus.f - 1, w_plus.e );
18495 
18496  decimal_exponent = -cached.k; // = -(-k) = k
18497 
18498  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
18499 }
18500 
18506 template<typename FloatType>
18508 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
18509 {
18510  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
18511  "internal error: not enough precision");
18512 
18513  JSON_ASSERT(std::isfinite(value));
18514  JSON_ASSERT(value > 0);
18515 
18516  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
18517  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
18518  // decimal representations are not exactly "short".
18519  //
18520  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
18521  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
18522  // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
18523  // does.
18524  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
18525  // representation using the corresponding std::from_chars function recovers value exactly". That
18526  // indicates that single precision floating-point numbers should be recovered using
18527  // 'std::strtof'.
18528  //
18529  // NB: If the neighbors are computed for single-precision numbers, there is a single float
18530  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
18531  // value is off by 1 ulp.
18532 #if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if)
18533  const boundaries w = compute_boundaries(static_cast<double>(value));
18534 #else
18535  const boundaries w = compute_boundaries(value);
18536 #endif
18537 
18538  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
18539 }
18540 
18548 inline char* append_exponent(char* buf, int e)
18549 {
18550  JSON_ASSERT(e > -1000);
18551  JSON_ASSERT(e < 1000);
18552 
18553  if (e < 0)
18554  {
18555  e = -e;
18556  *buf++ = '-';
18557  }
18558  else
18559  {
18560  *buf++ = '+';
18561  }
18562 
18563  auto k = static_cast<std::uint32_t>(e);
18564  if (k < 10)
18565  {
18566  // Always print at least two digits in the exponent.
18567  // This is for compatibility with printf("%g").
18568  *buf++ = '0';
18569  *buf++ = static_cast<char>('0' + k);
18570  }
18571  else if (k < 100)
18572  {
18573  *buf++ = static_cast<char>('0' + (k / 10));
18574  k %= 10;
18575  *buf++ = static_cast<char>('0' + k);
18576  }
18577  else
18578  {
18579  *buf++ = static_cast<char>('0' + (k / 100));
18580  k %= 100;
18581  *buf++ = static_cast<char>('0' + (k / 10));
18582  k %= 10;
18583  *buf++ = static_cast<char>('0' + k);
18584  }
18585 
18586  return buf;
18587 }
18588 
18600 inline char* format_buffer(char* buf, int len, int decimal_exponent,
18601  int min_exp, int max_exp)
18602 {
18603  JSON_ASSERT(min_exp < 0);
18604  JSON_ASSERT(max_exp > 0);
18605 
18606  const int k = len;
18607  const int n = len + decimal_exponent;
18608 
18609  // v = buf * 10^(n-k)
18610  // k is the length of the buffer (number of decimal digits)
18611  // n is the position of the decimal point relative to the start of the buffer.
18612 
18613  if (k <= n && n <= max_exp)
18614  {
18615  // digits[000]
18616  // len <= max_exp + 2
18617 
18618  std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
18619  // Make it look like a floating-point number (#362, #378)
18620  buf[n + 0] = '.';
18621  buf[n + 1] = '0';
18622  return buf + (static_cast<size_t>(n) + 2);
18623  }
18624 
18625  if (0 < n && n <= max_exp)
18626  {
18627  // dig.its
18628  // len <= max_digits10 + 1
18629 
18630  JSON_ASSERT(k > n);
18631 
18632  std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
18633  buf[n] = '.';
18634  return buf + (static_cast<size_t>(k) + 1U);
18635  }
18636 
18637  if (min_exp < n && n <= 0)
18638  {
18639  // 0.[000]digits
18640  // len <= 2 + (-min_exp - 1) + max_digits10
18641 
18642  std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
18643  buf[0] = '0';
18644  buf[1] = '.';
18645  std::memset(buf + 2, '0', static_cast<size_t>(-n));
18646  return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
18647  }
18648 
18649  if (k == 1)
18650  {
18651  // dE+123
18652  // len <= 1 + 5
18653 
18654  buf += 1;
18655  }
18656  else
18657  {
18658  // d.igitsE+123
18659  // len <= max_digits10 + 1 + 5
18660 
18661  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
18662  buf[1] = '.';
18663  buf += 1 + static_cast<size_t>(k);
18664  }
18665 
18666  *buf++ = 'e';
18667  return append_exponent(buf, n - 1);
18668 }
18669 
18670 } // namespace dtoa_impl
18671 
18682 template<typename FloatType>
18685 char* to_chars(char* first, const char* last, FloatType value)
18686 {
18687  static_cast<void>(last); // maybe unused - fix warning
18688  JSON_ASSERT(std::isfinite(value));
18689 
18690  // Use signbit(value) instead of (value < 0) since signbit works for -0.
18691  if (std::signbit(value))
18692  {
18693  value = -value;
18694  *first++ = '-';
18695  }
18696 
18697 #ifdef __GNUC__
18698 #pragma GCC diagnostic push
18699 #pragma GCC diagnostic ignored "-Wfloat-equal"
18700 #endif
18701  if (value == 0) // +-0
18702  {
18703  *first++ = '0';
18704  // Make it look like a floating-point number (#362, #378)
18705  *first++ = '.';
18706  *first++ = '0';
18707  return first;
18708  }
18709 #ifdef __GNUC__
18710 #pragma GCC diagnostic pop
18711 #endif
18712 
18713  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
18714 
18715  // Compute v = buffer * 10^decimal_exponent.
18716  // The decimal digits are stored in the buffer, which needs to be interpreted
18717  // as an unsigned decimal integer.
18718  // len is the length of the buffer, i.e. the number of decimal digits.
18719  int len = 0;
18720  int decimal_exponent = 0;
18721  dtoa_impl::grisu2(first, len, decimal_exponent, value);
18722 
18723  JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
18724 
18725  // Format the buffer like printf("%.*g", prec, value)
18726  constexpr int kMinExp = -4;
18727  // Use digits10 here to increase compatibility with version 2.
18728  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
18729 
18730  JSON_ASSERT(last - first >= kMaxExp + 2);
18731  JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
18732  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
18733 
18734  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
18735 }
18736 
18737 } // namespace detail
18739 
18740 // #include <nlohmann/detail/exceptions.hpp>
18741 
18742 // #include <nlohmann/detail/macro_scope.hpp>
18743 
18744 // #include <nlohmann/detail/meta/cpp_future.hpp>
18745 
18746 // #include <nlohmann/detail/output/binary_writer.hpp>
18747 
18748 // #include <nlohmann/detail/output/output_adapters.hpp>
18749 
18750 // #include <nlohmann/detail/string_concat.hpp>
18751 
18752 // #include <nlohmann/detail/value_t.hpp>
18753 
18754 
18756 namespace detail
18757 {
18758 
18760 // serialization //
18762 
18765 {
18766  strict,
18767  replace,
18768  ignore
18769 };
18770 
18771 template<typename BasicJsonType>
18773 {
18774  using string_t = typename BasicJsonType::string_t;
18775  using number_float_t = typename BasicJsonType::number_float_t;
18776  using number_integer_t = typename BasicJsonType::number_integer_t;
18777  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18778  using binary_char_t = typename BasicJsonType::binary_t::value_type;
18779  static constexpr std::uint8_t UTF8_ACCEPT = 0;
18780  static constexpr std::uint8_t UTF8_REJECT = 1;
18781 
18782  public:
18788  serializer(output_adapter_t<char> s, const char ichar,
18789  error_handler_t error_handler_ = error_handler_t::strict)
18790  : o(std::move(s))
18791  , loc(std::localeconv())
18792  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
18793  , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
18794  , indent_char(ichar)
18795  , indent_string(512, indent_char)
18796  , error_handler(error_handler_)
18797  {}
18798 
18799  // delete because of pointer members
18800  serializer(const serializer&) = delete;
18801  serializer& operator=(const serializer&) = delete;
18802  serializer(serializer&&) = delete;
18804  ~serializer() = default;
18805 
18828  void dump(const BasicJsonType& val,
18829  const bool pretty_print,
18830  const bool ensure_ascii,
18831  const unsigned int indent_step,
18832  const unsigned int current_indent = 0)
18833  {
18834  switch (val.m_data.m_type)
18835  {
18836  case value_t::object:
18837  {
18838  if (val.m_data.m_value.object->empty())
18839  {
18840  o->write_characters("{}", 2);
18841  return;
18842  }
18843 
18844  if (pretty_print)
18845  {
18846  o->write_characters("{\n", 2);
18847 
18848  // variable to hold indentation for recursive calls
18849  const auto new_indent = current_indent + indent_step;
18850  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18851  {
18852  indent_string.resize(indent_string.size() * 2, ' ');
18853  }
18854 
18855  // first n-1 elements
18856  auto i = val.m_data.m_value.object->cbegin();
18857  for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18858  {
18859  o->write_characters(indent_string.c_str(), new_indent);
18860  o->write_character('\"');
18861  dump_escaped(i->first, ensure_ascii);
18862  o->write_characters("\": ", 3);
18863  dump(i->second, true, ensure_ascii, indent_step, new_indent);
18864  o->write_characters(",\n", 2);
18865  }
18866 
18867  // last element
18868  JSON_ASSERT(i != val.m_data.m_value.object->cend());
18869  JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18870  o->write_characters(indent_string.c_str(), new_indent);
18871  o->write_character('\"');
18872  dump_escaped(i->first, ensure_ascii);
18873  o->write_characters("\": ", 3);
18874  dump(i->second, true, ensure_ascii, indent_step, new_indent);
18875 
18876  o->write_character('\n');
18877  o->write_characters(indent_string.c_str(), current_indent);
18878  o->write_character('}');
18879  }
18880  else
18881  {
18882  o->write_character('{');
18883 
18884  // first n-1 elements
18885  auto i = val.m_data.m_value.object->cbegin();
18886  for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18887  {
18888  o->write_character('\"');
18889  dump_escaped(i->first, ensure_ascii);
18890  o->write_characters("\":", 2);
18891  dump(i->second, false, ensure_ascii, indent_step, current_indent);
18892  o->write_character(',');
18893  }
18894 
18895  // last element
18896  JSON_ASSERT(i != val.m_data.m_value.object->cend());
18897  JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18898  o->write_character('\"');
18899  dump_escaped(i->first, ensure_ascii);
18900  o->write_characters("\":", 2);
18901  dump(i->second, false, ensure_ascii, indent_step, current_indent);
18902 
18903  o->write_character('}');
18904  }
18905 
18906  return;
18907  }
18908 
18909  case value_t::array:
18910  {
18911  if (val.m_data.m_value.array->empty())
18912  {
18913  o->write_characters("[]", 2);
18914  return;
18915  }
18916 
18917  if (pretty_print)
18918  {
18919  o->write_characters("[\n", 2);
18920 
18921  // variable to hold indentation for recursive calls
18922  const auto new_indent = current_indent + indent_step;
18923  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18924  {
18925  indent_string.resize(indent_string.size() * 2, ' ');
18926  }
18927 
18928  // first n-1 elements
18929  for (auto i = val.m_data.m_value.array->cbegin();
18930  i != val.m_data.m_value.array->cend() - 1; ++i)
18931  {
18932  o->write_characters(indent_string.c_str(), new_indent);
18933  dump(*i, true, ensure_ascii, indent_step, new_indent);
18934  o->write_characters(",\n", 2);
18935  }
18936 
18937  // last element
18938  JSON_ASSERT(!val.m_data.m_value.array->empty());
18939  o->write_characters(indent_string.c_str(), new_indent);
18940  dump(val.m_data.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
18941 
18942  o->write_character('\n');
18943  o->write_characters(indent_string.c_str(), current_indent);
18944  o->write_character(']');
18945  }
18946  else
18947  {
18948  o->write_character('[');
18949 
18950  // first n-1 elements
18951  for (auto i = val.m_data.m_value.array->cbegin();
18952  i != val.m_data.m_value.array->cend() - 1; ++i)
18953  {
18954  dump(*i, false, ensure_ascii, indent_step, current_indent);
18955  o->write_character(',');
18956  }
18957 
18958  // last element
18959  JSON_ASSERT(!val.m_data.m_value.array->empty());
18960  dump(val.m_data.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
18961 
18962  o->write_character(']');
18963  }
18964 
18965  return;
18966  }
18967 
18968  case value_t::string:
18969  {
18970  o->write_character('\"');
18971  dump_escaped(*val.m_data.m_value.string, ensure_ascii);
18972  o->write_character('\"');
18973  return;
18974  }
18975 
18976  case value_t::binary:
18977  {
18978  if (pretty_print)
18979  {
18980  o->write_characters("{\n", 2);
18981 
18982  // variable to hold indentation for recursive calls
18983  const auto new_indent = current_indent + indent_step;
18984  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18985  {
18986  indent_string.resize(indent_string.size() * 2, ' ');
18987  }
18988 
18989  o->write_characters(indent_string.c_str(), new_indent);
18990 
18991  o->write_characters("\"bytes\": [", 10);
18992 
18993  if (!val.m_data.m_value.binary->empty())
18994  {
18995  for (auto i = val.m_data.m_value.binary->cbegin();
18996  i != val.m_data.m_value.binary->cend() - 1; ++i)
18997  {
18998  dump_integer(*i);
18999  o->write_characters(", ", 2);
19000  }
19001  dump_integer(val.m_data.m_value.binary->back());
19002  }
19003 
19004  o->write_characters("],\n", 3);
19005  o->write_characters(indent_string.c_str(), new_indent);
19006 
19007  o->write_characters("\"subtype\": ", 11);
19008  if (val.m_data.m_value.binary->has_subtype())
19009  {
19010  dump_integer(val.m_data.m_value.binary->subtype());
19011  }
19012  else
19013  {
19014  o->write_characters("null", 4);
19015  }
19016  o->write_character('\n');
19017  o->write_characters(indent_string.c_str(), current_indent);
19018  o->write_character('}');
19019  }
19020  else
19021  {
19022  o->write_characters("{\"bytes\":[", 10);
19023 
19024  if (!val.m_data.m_value.binary->empty())
19025  {
19026  for (auto i = val.m_data.m_value.binary->cbegin();
19027  i != val.m_data.m_value.binary->cend() - 1; ++i)
19028  {
19029  dump_integer(*i);
19030  o->write_character(',');
19031  }
19032  dump_integer(val.m_data.m_value.binary->back());
19033  }
19034 
19035  o->write_characters("],\"subtype\":", 12);
19036  if (val.m_data.m_value.binary->has_subtype())
19037  {
19038  dump_integer(val.m_data.m_value.binary->subtype());
19039  o->write_character('}');
19040  }
19041  else
19042  {
19043  o->write_characters("null}", 5);
19044  }
19045  }
19046  return;
19047  }
19048 
19049  case value_t::boolean:
19050  {
19051  if (val.m_data.m_value.boolean)
19052  {
19053  o->write_characters("true", 4);
19054  }
19055  else
19056  {
19057  o->write_characters("false", 5);
19058  }
19059  return;
19060  }
19061 
19062  case value_t::number_integer:
19063  {
19064  dump_integer(val.m_data.m_value.number_integer);
19065  return;
19066  }
19067 
19068  case value_t::number_unsigned:
19069  {
19070  dump_integer(val.m_data.m_value.number_unsigned);
19071  return;
19072  }
19073 
19074  case value_t::number_float:
19075  {
19076  dump_float(val.m_data.m_value.number_float);
19077  return;
19078  }
19079 
19080  case value_t::discarded:
19081  {
19082  o->write_characters("<discarded>", 11);
19083  return;
19084  }
19085 
19086  case value_t::null:
19087  {
19088  o->write_characters("null", 4);
19089  return;
19090  }
19091 
19092  default: // LCOV_EXCL_LINE
19093  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19094  }
19095  }
19096 
19112  void dump_escaped(const string_t& s, const bool ensure_ascii)
19113  {
19114  std::uint32_t codepoint{};
19115  std::uint8_t state = UTF8_ACCEPT;
19116  std::size_t bytes = 0; // number of bytes written to string_buffer
19117 
19118  // number of bytes written at the point of the last valid byte
19119  std::size_t bytes_after_last_accept = 0;
19120  std::size_t undumped_chars = 0;
19121 
19122  for (std::size_t i = 0; i < s.size(); ++i)
19123  {
19124  const auto byte = static_cast<std::uint8_t>(s[i]);
19125 
19126  switch (decode(state, codepoint, byte))
19127  {
19128  case UTF8_ACCEPT: // decode found a new code point
19129  {
19130  switch (codepoint)
19131  {
19132  case 0x08: // backspace
19133  {
19134  string_buffer[bytes++] = '\\';
19135  string_buffer[bytes++] = 'b';
19136  break;
19137  }
19138 
19139  case 0x09: // horizontal tab
19140  {
19141  string_buffer[bytes++] = '\\';
19142  string_buffer[bytes++] = 't';
19143  break;
19144  }
19145 
19146  case 0x0A: // newline
19147  {
19148  string_buffer[bytes++] = '\\';
19149  string_buffer[bytes++] = 'n';
19150  break;
19151  }
19152 
19153  case 0x0C: // formfeed
19154  {
19155  string_buffer[bytes++] = '\\';
19156  string_buffer[bytes++] = 'f';
19157  break;
19158  }
19159 
19160  case 0x0D: // carriage return
19161  {
19162  string_buffer[bytes++] = '\\';
19163  string_buffer[bytes++] = 'r';
19164  break;
19165  }
19166 
19167  case 0x22: // quotation mark
19168  {
19169  string_buffer[bytes++] = '\\';
19170  string_buffer[bytes++] = '\"';
19171  break;
19172  }
19173 
19174  case 0x5C: // reverse solidus
19175  {
19176  string_buffer[bytes++] = '\\';
19177  string_buffer[bytes++] = '\\';
19178  break;
19179  }
19180 
19181  default:
19182  {
19183  // escape control characters (0x00..0x1F) or, if
19184  // ensure_ascii parameter is used, non-ASCII characters
19185  if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
19186  {
19187  if (codepoint <= 0xFFFF)
19188  {
19189  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
19190  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
19191  static_cast<std::uint16_t>(codepoint)));
19192  bytes += 6;
19193  }
19194  else
19195  {
19196  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
19197  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
19198  static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
19199  static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
19200  bytes += 12;
19201  }
19202  }
19203  else
19204  {
19205  // copy byte to buffer (all previous bytes
19206  // been copied have in default case above)
19207  string_buffer[bytes++] = s[i];
19208  }
19209  break;
19210  }
19211  }
19212 
19213  // write buffer and reset index; there must be 13 bytes
19214  // left, as this is the maximal number of bytes to be
19215  // written ("\uxxxx\uxxxx\0") for one code point
19216  if (string_buffer.size() - bytes < 13)
19217  {
19218  o->write_characters(string_buffer.data(), bytes);
19219  bytes = 0;
19220  }
19221 
19222  // remember the byte position of this accept
19223  bytes_after_last_accept = bytes;
19224  undumped_chars = 0;
19225  break;
19226  }
19227 
19228  case UTF8_REJECT: // decode found invalid UTF-8 byte
19229  {
19230  switch (error_handler)
19231  {
19232  case error_handler_t::strict:
19233  {
19234  JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
19235  }
19236 
19237  case error_handler_t::ignore:
19238  case error_handler_t::replace:
19239  {
19240  // in case we saw this character the first time, we
19241  // would like to read it again, because the byte
19242  // may be OK for itself, but just not OK for the
19243  // previous sequence
19244  if (undumped_chars > 0)
19245  {
19246  --i;
19247  }
19248 
19249  // reset length buffer to the last accepted index;
19250  // thus removing/ignoring the invalid characters
19251  bytes = bytes_after_last_accept;
19252 
19253  if (error_handler == error_handler_t::replace)
19254  {
19255  // add a replacement character
19256  if (ensure_ascii)
19257  {
19258  string_buffer[bytes++] = '\\';
19259  string_buffer[bytes++] = 'u';
19260  string_buffer[bytes++] = 'f';
19261  string_buffer[bytes++] = 'f';
19262  string_buffer[bytes++] = 'f';
19263  string_buffer[bytes++] = 'd';
19264  }
19265  else
19266  {
19267  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
19268  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
19269  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
19270  }
19271 
19272  // write buffer and reset index; there must be 13 bytes
19273  // left, as this is the maximal number of bytes to be
19274  // written ("\uxxxx\uxxxx\0") for one code point
19275  if (string_buffer.size() - bytes < 13)
19276  {
19277  o->write_characters(string_buffer.data(), bytes);
19278  bytes = 0;
19279  }
19280 
19281  bytes_after_last_accept = bytes;
19282  }
19283 
19284  undumped_chars = 0;
19285 
19286  // continue processing the string
19287  state = UTF8_ACCEPT;
19288  break;
19289  }
19290 
19291  default: // LCOV_EXCL_LINE
19292  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19293  }
19294  break;
19295  }
19296 
19297  default: // decode found yet incomplete multi-byte code point
19298  {
19299  if (!ensure_ascii)
19300  {
19301  // code point will not be escaped - copy byte to buffer
19302  string_buffer[bytes++] = s[i];
19303  }
19304  ++undumped_chars;
19305  break;
19306  }
19307  }
19308  }
19309 
19310  // we finished processing the string
19311  if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
19312  {
19313  // write buffer
19314  if (bytes > 0)
19315  {
19316  o->write_characters(string_buffer.data(), bytes);
19317  }
19318  }
19319  else
19320  {
19321  // we finish reading, but do not accept: string was incomplete
19322  switch (error_handler)
19323  {
19324  case error_handler_t::strict:
19325  {
19326  JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));
19327  }
19328 
19329  case error_handler_t::ignore:
19330  {
19331  // write all accepted bytes
19332  o->write_characters(string_buffer.data(), bytes_after_last_accept);
19333  break;
19334  }
19335 
19336  case error_handler_t::replace:
19337  {
19338  // write all accepted bytes
19339  o->write_characters(string_buffer.data(), bytes_after_last_accept);
19340  // add a replacement character
19341  if (ensure_ascii)
19342  {
19343  o->write_characters("\\ufffd", 6);
19344  }
19345  else
19346  {
19347  o->write_characters("\xEF\xBF\xBD", 3);
19348  }
19349  break;
19350  }
19351 
19352  default: // LCOV_EXCL_LINE
19353  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19354  }
19355  }
19356  }
19357 
19358  private:
19367  unsigned int count_digits(number_unsigned_t x) noexcept
19368  {
19369  unsigned int n_digits = 1;
19370  for (;;)
19371  {
19372  if (x < 10)
19373  {
19374  return n_digits;
19375  }
19376  if (x < 100)
19377  {
19378  return n_digits + 1;
19379  }
19380  if (x < 1000)
19381  {
19382  return n_digits + 2;
19383  }
19384  if (x < 10000)
19385  {
19386  return n_digits + 3;
19387  }
19388  x = x / 10000u;
19389  n_digits += 4;
19390  }
19391  }
19392 
19398  static std::string hex_bytes(std::uint8_t byte)
19399  {
19400  std::string result = "FF";
19401  constexpr const char* nibble_to_hex = "0123456789ABCDEF";
19402  result[0] = nibble_to_hex[byte / 16];
19403  result[1] = nibble_to_hex[byte % 16];
19404  return result;
19405  }
19406 
19407  // templates to avoid warnings about useless casts
19408  template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
19409  bool is_negative_number(NumberType x)
19410  {
19411  return x < 0;
19412  }
19413 
19414  template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
19415  bool is_negative_number(NumberType /*unused*/)
19416  {
19417  return false;
19418  }
19419 
19429  template < typename NumberType, detail::enable_if_t <
19430  std::is_integral<NumberType>::value ||
19431  std::is_same<NumberType, number_unsigned_t>::value ||
19432  std::is_same<NumberType, number_integer_t>::value ||
19433  std::is_same<NumberType, binary_char_t>::value,
19434  int > = 0 >
19435  void dump_integer(NumberType x)
19436  {
19437  static constexpr std::array<std::array<char, 2>, 100> digits_to_99
19438  {
19439  {
19440  {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
19441  {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
19442  {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
19443  {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
19444  {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
19445  {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
19446  {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
19447  {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
19448  {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
19449  {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
19450  }
19451  };
19452 
19453  // special case for "0"
19454  if (x == 0)
19455  {
19456  o->write_character('0');
19457  return;
19458  }
19459 
19460  // use a pointer to fill the buffer
19461  auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
19462 
19463  number_unsigned_t abs_value;
19464 
19465  unsigned int n_chars{};
19466 
19467  if (is_negative_number(x))
19468  {
19469  *buffer_ptr = '-';
19470  abs_value = remove_sign(static_cast<number_integer_t>(x));
19471 
19472  // account one more byte for the minus sign
19473  n_chars = 1 + count_digits(abs_value);
19474  }
19475  else
19476  {
19477  abs_value = static_cast<number_unsigned_t>(x);
19478  n_chars = count_digits(abs_value);
19479  }
19480 
19481  // spare 1 byte for '\0'
19482  JSON_ASSERT(n_chars < number_buffer.size() - 1);
19483 
19484  // jump to the end to generate the string from backward,
19485  // so we later avoid reversing the result
19486  buffer_ptr += n_chars;
19487 
19488  // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
19489  // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
19490  while (abs_value >= 100)
19491  {
19492  const auto digits_index = static_cast<unsigned>((abs_value % 100));
19493  abs_value /= 100;
19494  *(--buffer_ptr) = digits_to_99[digits_index][1];
19495  *(--buffer_ptr) = digits_to_99[digits_index][0];
19496  }
19497 
19498  if (abs_value >= 10)
19499  {
19500  const auto digits_index = static_cast<unsigned>(abs_value);
19501  *(--buffer_ptr) = digits_to_99[digits_index][1];
19502  *(--buffer_ptr) = digits_to_99[digits_index][0];
19503  }
19504  else
19505  {
19506  *(--buffer_ptr) = static_cast<char>('0' + abs_value);
19507  }
19508 
19509  o->write_characters(number_buffer.data(), n_chars);
19510  }
19511 
19520  void dump_float(number_float_t x)
19521  {
19522  // NaN / inf
19523  if (!std::isfinite(x))
19524  {
19525  o->write_characters("null", 4);
19526  return;
19527  }
19528 
19529  // If number_float_t is an IEEE-754 single or double precision number,
19530  // use the Grisu2 algorithm to produce short numbers which are
19531  // guaranteed to round-trip, using strtof and strtod, resp.
19532  //
19533  // NB: The test below works if <long double> == <double>.
19534  static constexpr bool is_ieee_single_or_double
19535  = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
19536  (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
19537 
19538  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
19539  }
19540 
19541  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
19542  {
19543  auto* begin = number_buffer.data();
19544  auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
19545 
19546  o->write_characters(begin, static_cast<size_t>(end - begin));
19547  }
19548 
19549  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
19550  {
19551  // get number of digits for a float -> text -> float round-trip
19552  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
19553 
19554  // the actual conversion
19555  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
19556  std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
19557 
19558  // negative value indicates an error
19559  JSON_ASSERT(len > 0);
19560  // check if buffer was large enough
19561  JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
19562 
19563  // erase thousands separator
19564  if (thousands_sep != '\0')
19565  {
19566  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
19567  const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
19568  std::fill(end, number_buffer.end(), '\0');
19569  JSON_ASSERT((end - number_buffer.begin()) <= len);
19570  len = (end - number_buffer.begin());
19571  }
19572 
19573  // convert decimal point to '.'
19574  if (decimal_point != '\0' && decimal_point != '.')
19575  {
19576  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
19577  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
19578  if (dec_pos != number_buffer.end())
19579  {
19580  *dec_pos = '.';
19581  }
19582  }
19583 
19584  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
19585 
19586  // determine if we need to append ".0"
19587  const bool value_is_int_like =
19588  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
19589  [](char c)
19590  {
19591  return c == '.' || c == 'e';
19592  });
19593 
19594  if (value_is_int_like)
19595  {
19596  o->write_characters(".0", 2);
19597  }
19598  }
19599 
19621  static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
19622  {
19623  static const std::array<std::uint8_t, 400> utf8d =
19624  {
19625  {
19626  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
19627  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
19628  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
19629  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
19630  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
19631  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
19632  8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
19633  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
19634  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
19635  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
19636  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
19637  1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
19638  1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
19639  1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
19640  }
19641  };
19642 
19643  JSON_ASSERT(byte < utf8d.size());
19644  const std::uint8_t type = utf8d[byte];
19645 
19646  codep = (state != UTF8_ACCEPT)
19647  ? (byte & 0x3fu) | (codep << 6u)
19648  : (0xFFu >> type) & (byte);
19649 
19650  const std::size_t index = 256u + (static_cast<size_t>(state) * 16u) + static_cast<size_t>(type);
19651  JSON_ASSERT(index < utf8d.size());
19652  state = utf8d[index];
19653  return state;
19654  }
19655 
19656  /*
19657  * Overload to make the compiler happy while it is instantiating
19658  * dump_integer for number_unsigned_t.
19659  * Must never be called.
19660  */
19661  number_unsigned_t remove_sign(number_unsigned_t x)
19662  {
19663  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19664  return x; // LCOV_EXCL_LINE
19665  }
19666 
19667  /*
19668  * Helper function for dump_integer
19669  *
19670  * This function takes a negative signed integer and returns its absolute
19671  * value as unsigned integer. The plus/minus shuffling is necessary as we can
19672  * not directly remove the sign of an arbitrary signed integer as the
19673  * absolute values of INT_MIN and INT_MAX are usually not the same. See
19674  * #1708 for details.
19675  */
19676  number_unsigned_t remove_sign(number_integer_t x) noexcept
19677  {
19678  JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
19679  return static_cast<number_unsigned_t>(-(x + 1)) + 1;
19680  }
19681 
19682  private:
19684  output_adapter_t<char> o = nullptr;
19685 
19687  std::array<char, 64> number_buffer{{}};
19688 
19690  const std::lconv* loc = nullptr;
19692  const char thousands_sep = '\0';
19694  const char decimal_point = '\0';
19695 
19697  std::array<char, 512> string_buffer{{}};
19698 
19700  const char indent_char;
19702  string_t indent_string;
19703 
19706 };
19707 
19708 } // namespace detail
19710 
19711 // #include <nlohmann/detail/value_t.hpp>
19712 
19713 // #include <nlohmann/json_fwd.hpp>
19714 
19715 // #include <nlohmann/ordered_map.hpp>
19716 // __ _____ _____ _____
19717 // __| | __| | | | JSON for Modern C++
19718 // | | |__ | | | | | | version 3.12.0
19719 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
19720 //
19721 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
19722 // SPDX-License-Identifier: MIT
19723 
19724 
19725 
19726 #include <functional> // equal_to, less
19727 #include <initializer_list> // initializer_list
19728 #include <iterator> // input_iterator_tag, iterator_traits
19729 #include <memory> // allocator
19730 #include <stdexcept> // for out_of_range
19731 #include <type_traits> // enable_if, is_convertible
19732 #include <utility> // pair
19733 #include <vector> // vector
19734 
19735 // #include <nlohmann/detail/macro_scope.hpp>
19736 
19737 // #include <nlohmann/detail/meta/type_traits.hpp>
19738 
19739 
19741 
19744 template <class Key, class T, class IgnoredLess = std::less<Key>,
19745  class Allocator = std::allocator<std::pair<const Key, T>>>
19746  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
19747 {
19748  using key_type = Key;
19749  using mapped_type = T;
19750  using Container = std::vector<std::pair<const Key, T>, Allocator>;
19751  using iterator = typename Container::iterator;
19752  using const_iterator = typename Container::const_iterator;
19753  using size_type = typename Container::size_type;
19754  using value_type = typename Container::value_type;
19755 #ifdef JSON_HAS_CPP_14
19756  using key_compare = std::equal_to<>;
19757 #else
19758  using key_compare = std::equal_to<Key>;
19759 #endif
19760 
19761  // Explicit constructors instead of `using Container::Container`
19762  // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
19763  ordered_map() noexcept(noexcept(Container())) : Container{} {}
19764  explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
19765  template <class It>
19766  ordered_map(It first, It last, const Allocator& alloc = Allocator())
19767  : Container{first, last, alloc} {}
19768  ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
19769  : Container{init, alloc} {}
19770 
19771  std::pair<iterator, bool> emplace(const key_type& key, T&& t)
19772  {
19773  for (auto it = this->begin(); it != this->end(); ++it)
19774  {
19775  if (m_compare(it->first, key))
19776  {
19777  return {it, false};
19778  }
19779  }
19780  Container::emplace_back(key, std::forward<T>(t));
19781  return {std::prev(this->end()), true};
19782  }
19783 
19784  template<class KeyType, detail::enable_if_t<
19786  std::pair<iterator, bool> emplace(KeyType && key, T && t)
19787  {
19788  for (auto it = this->begin(); it != this->end(); ++it)
19789  {
19790  if (m_compare(it->first, key))
19791  {
19792  return {it, false};
19793  }
19794  }
19795  Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
19796  return {std::prev(this->end()), true};
19797  }
19798 
19800  {
19801  return emplace(key, T{}).first->second;
19802  }
19803 
19804  template<class KeyType, detail::enable_if_t<
19806  T & operator[](KeyType && key)
19807  {
19808  return emplace(std::forward<KeyType>(key), T{}).first->second;
19809  }
19810 
19811  const T& operator[](const key_type& key) const
19812  {
19813  return at(key);
19814  }
19815 
19816  template<class KeyType, detail::enable_if_t<
19818  const T & operator[](KeyType && key) const
19819  {
19820  return at(std::forward<KeyType>(key));
19821  }
19822 
19823  T& at(const key_type& key)
19824  {
19825  for (auto it = this->begin(); it != this->end(); ++it)
19826  {
19827  if (m_compare(it->first, key))
19828  {
19829  return it->second;
19830  }
19831  }
19832 
19833  JSON_THROW(std::out_of_range("key not found"));
19834  }
19835 
19836  template<class KeyType, detail::enable_if_t<
19838  T & at(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
19839  {
19840  for (auto it = this->begin(); it != this->end(); ++it)
19841  {
19842  if (m_compare(it->first, key))
19843  {
19844  return it->second;
19845  }
19846  }
19847 
19848  JSON_THROW(std::out_of_range("key not found"));
19849  }
19850 
19851  const T& at(const key_type& key) const
19852  {
19853  for (auto it = this->begin(); it != this->end(); ++it)
19854  {
19855  if (m_compare(it->first, key))
19856  {
19857  return it->second;
19858  }
19859  }
19860 
19861  JSON_THROW(std::out_of_range("key not found"));
19862  }
19863 
19864  template<class KeyType, detail::enable_if_t<
19866  const T & at(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)
19867  {
19868  for (auto it = this->begin(); it != this->end(); ++it)
19869  {
19870  if (m_compare(it->first, key))
19871  {
19872  return it->second;
19873  }
19874  }
19875 
19876  JSON_THROW(std::out_of_range("key not found"));
19877  }
19878 
19880  {
19881  for (auto it = this->begin(); it != this->end(); ++it)
19882  {
19883  if (m_compare(it->first, key))
19884  {
19885  // Since we cannot move const Keys, re-construct them in place
19886  for (auto next = it; ++next != this->end(); ++it)
19887  {
19888  it->~value_type(); // Destroy but keep allocation
19889  new (&*it) value_type{std::move(*next)};
19890  }
19891  Container::pop_back();
19892  return 1;
19893  }
19894  }
19895  return 0;
19896  }
19897 
19898  template<class KeyType, detail::enable_if_t<
19900  size_type erase(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
19901  {
19902  for (auto it = this->begin(); it != this->end(); ++it)
19903  {
19904  if (m_compare(it->first, key))
19905  {
19906  // Since we cannot move const Keys, re-construct them in place
19907  for (auto next = it; ++next != this->end(); ++it)
19908  {
19909  it->~value_type(); // Destroy but keep allocation
19910  new (&*it) value_type{std::move(*next)};
19911  }
19912  Container::pop_back();
19913  return 1;
19914  }
19915  }
19916  return 0;
19917  }
19918 
19920  {
19921  return erase(pos, std::next(pos));
19922  }
19923 
19925  {
19926  if (first == last)
19927  {
19928  return first;
19929  }
19930 
19931  const auto elements_affected = std::distance(first, last);
19932  const auto offset = std::distance(Container::begin(), first);
19933 
19934  // This is the start situation. We need to delete elements_affected
19935  // elements (3 in this example: e, f, g), and need to return an
19936  // iterator past the last deleted element (h in this example).
19937  // Note that offset is the distance from the start of the vector
19938  // to first. We will need this later.
19939 
19940  // [ a, b, c, d, e, f, g, h, i, j ]
19941  // ^ ^
19942  // first last
19943 
19944  // Since we cannot move const Keys, we re-construct them in place.
19945  // We start at first and re-construct (viz. copy) the elements from
19946  // the back of the vector. Example for first iteration:
19947 
19948  // ,--------.
19949  // v | destroy e and re-construct with h
19950  // [ a, b, c, d, e, f, g, h, i, j ]
19951  // ^ ^
19952  // it it + elements_affected
19953 
19954  for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
19955  {
19956  it->~value_type(); // destroy but keep allocation
19957  new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
19958  }
19959 
19960  // [ a, b, c, d, h, i, j, h, i, j ]
19961  // ^ ^
19962  // first last
19963 
19964  // remove the unneeded elements at the end of the vector
19965  Container::resize(this->size() - static_cast<size_type>(elements_affected));
19966 
19967  // [ a, b, c, d, h, i, j ]
19968  // ^ ^
19969  // first last
19970 
19971  // first is now pointing past the last deleted element, but we cannot
19972  // use this iterator, because it may have been invalidated by the
19973  // resize call. Instead, we can return begin() + offset.
19974  return Container::begin() + offset;
19975  }
19976 
19977  size_type count(const key_type& key) const
19978  {
19979  for (auto it = this->begin(); it != this->end(); ++it)
19980  {
19981  if (m_compare(it->first, key))
19982  {
19983  return 1;
19984  }
19985  }
19986  return 0;
19987  }
19988 
19989  template<class KeyType, detail::enable_if_t<
19991  size_type count(KeyType && key) const // NOLINT(cppcoreguidelines-missing-std-forward)
19992  {
19993  for (auto it = this->begin(); it != this->end(); ++it)
19994  {
19995  if (m_compare(it->first, key))
19996  {
19997  return 1;
19998  }
19999  }
20000  return 0;
20001  }
20002 
20004  {
20005  for (auto it = this->begin(); it != this->end(); ++it)
20006  {
20007  if (m_compare(it->first, key))
20008  {
20009  return it;
20010  }
20011  }
20012  return Container::end();
20013  }
20014 
20015  template<class KeyType, detail::enable_if_t<
20017  iterator find(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
20018  {
20019  for (auto it = this->begin(); it != this->end(); ++it)
20020  {
20021  if (m_compare(it->first, key))
20022  {
20023  return it;
20024  }
20025  }
20026  return Container::end();
20027  }
20028 
20030  {
20031  for (auto it = this->begin(); it != this->end(); ++it)
20032  {
20033  if (m_compare(it->first, key))
20034  {
20035  return it;
20036  }
20037  }
20038  return Container::end();
20039  }
20040 
20041  std::pair<iterator, bool> insert( value_type&& value )
20042  {
20043  return emplace(value.first, std::move(value.second));
20044  }
20045 
20046  std::pair<iterator, bool> insert( const value_type& value )
20047  {
20048  for (auto it = this->begin(); it != this->end(); ++it)
20049  {
20050  if (m_compare(it->first, value.first))
20051  {
20052  return {it, false};
20053  }
20054  }
20055  Container::push_back(value);
20056  return {--this->end(), true};
20057  }
20058 
20059  template<typename InputIt>
20060  using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
20061  std::input_iterator_tag>::value>::type;
20062 
20063  template<typename InputIt, typename = require_input_iter<InputIt>>
20064  void insert(InputIt first, InputIt last)
20065  {
20066  for (auto it = first; it != last; ++it)
20067  {
20068  insert(*it);
20069  }
20070  }
20071 
20072 private:
20073  JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare();
20074 };
20075 
20077 
20078 
20079 #if defined(JSON_HAS_CPP_17)
20080  #if JSON_HAS_STATIC_RTTI
20081  #include <any>
20082  #endif
20083  #include <string_view>
20084 #endif
20085 
20092 
20112 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
20113  : public ::nlohmann::detail::json_base_class<CustomBaseClass>
20114 {
20115  private:
20116  template<detail::value_t> friend struct detail::external_constructor;
20117 
20118  template<typename>
20119  friend class ::nlohmann::json_pointer;
20120  // can be restored when json_pointer backwards compatibility is removed
20121  // friend ::nlohmann::json_pointer<StringType>;
20122 
20123  template<typename BasicJsonType, typename InputType>
20124  friend class ::nlohmann::detail::parser;
20125  friend ::nlohmann::detail::serializer<basic_json>;
20126  template<typename BasicJsonType>
20127  friend class ::nlohmann::detail::iter_impl;
20128  template<typename BasicJsonType, typename CharType>
20129  friend class ::nlohmann::detail::binary_writer;
20130  template<typename BasicJsonType, typename InputType, typename SAX>
20131  friend class ::nlohmann::detail::binary_reader;
20132  template<typename BasicJsonType, typename InputAdapterType>
20133  friend class ::nlohmann::detail::json_sax_dom_parser;
20134  template<typename BasicJsonType, typename InputAdapterType>
20135  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
20136  friend class ::nlohmann::detail::exception;
20137 
20139  using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
20140  using json_base_class_t = ::nlohmann::detail::json_base_class<CustomBaseClass>;
20141 
20143  // convenience aliases for types residing in namespace detail;
20144  using lexer = ::nlohmann::detail::lexer_base<basic_json>;
20145 
20146  template<typename InputAdapterType>
20147  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
20148  InputAdapterType adapter,
20150  const bool allow_exceptions = true,
20151  const bool ignore_comments = false
20152  )
20153  {
20154  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
20155  std::move(cb), allow_exceptions, ignore_comments);
20156  }
20157 
20158  private:
20159  using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
20160  template<typename BasicJsonType>
20161  using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
20162  template<typename BasicJsonType>
20163  using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
20164  template<typename Iterator>
20165  using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
20166  template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
20167 
20168  template<typename CharType>
20169  using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
20170 
20171  template<typename InputType>
20172  using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
20173  template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
20174 
20176  using serializer = ::nlohmann::detail::serializer<basic_json>;
20177 
20178  public:
20181  using json_pointer = ::nlohmann::json_pointer<StringType>;
20182  template<typename T, typename SFINAE>
20183  using json_serializer = JSONSerializer<T, SFINAE>;
20191  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
20192 
20196 
20198  // exceptions //
20200 
20204 
20211 
20213 
20215  // container types //
20217 
20222 
20225 
20229  using const_reference = const value_type&;
20230 
20232  using difference_type = std::ptrdiff_t;
20234  using size_type = std::size_t;
20235 
20237  using allocator_type = AllocatorType<basic_json>;
20238 
20240  using pointer = typename std::allocator_traits<allocator_type>::pointer;
20242  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
20243 
20245  using iterator = iter_impl<basic_json>;
20247  using const_iterator = iter_impl<const basic_json>;
20249  using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
20251  using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
20252 
20254 
20258  {
20259  return allocator_type();
20260  }
20261 
20265  static basic_json meta()
20266  {
20267  basic_json result;
20268 
20269  result["copyright"] = "(C) 2013-2025 Niels Lohmann";
20270  result["name"] = "JSON for Modern C++";
20271  result["url"] = "https://github.com/nlohmann/json";
20272  result["version"]["string"] =
20276  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
20277  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
20278  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
20279 
20280 #ifdef _WIN32
20281  result["platform"] = "win32";
20282 #elif defined __linux__
20283  result["platform"] = "linux";
20284 #elif defined __APPLE__
20285  result["platform"] = "apple";
20286 #elif defined __unix__
20287  result["platform"] = "unix";
20288 #else
20289  result["platform"] = "unknown";
20290 #endif
20291 
20292 #if defined(__ICC) || defined(__INTEL_COMPILER)
20293  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
20294 #elif defined(__clang__)
20295  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
20296 #elif defined(__GNUC__) || defined(__GNUG__)
20297  result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
20298  std::to_string(__GNUC__), '.',
20299  std::to_string(__GNUC_MINOR__), '.',
20300  std::to_string(__GNUC_PATCHLEVEL__))
20301  }
20302  };
20303 #elif defined(__HP_cc) || defined(__HP_aCC)
20304  result["compiler"] = "hp"
20305 #elif defined(__IBMCPP__)
20306  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
20307 #elif defined(_MSC_VER)
20308  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
20309 #elif defined(__PGI)
20310  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
20311 #elif defined(__SUNPRO_CC)
20312  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
20313 #else
20314  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
20315 #endif
20316 
20317 #if defined(_MSVC_LANG)
20318  result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
20319 #elif defined(__cplusplus)
20320  result["compiler"]["c++"] = std::to_string(__cplusplus);
20321 #else
20322  result["compiler"]["c++"] = "unknown";
20323 #endif
20324  return result;
20325  }
20326 
20328  // JSON value data types //
20330 
20335 
20340 #if defined(JSON_HAS_CPP_14)
20341  // use of transparent comparator avoids unnecessary repeated construction of temporaries
20342  // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
20343  using default_object_comparator_t = std::less<>;
20344 #else
20345  using default_object_comparator_t = std::less<StringType>;
20346 #endif
20347 
20350  using object_t = ObjectType<StringType,
20351  basic_json,
20353  AllocatorType<std::pair<const StringType,
20354  basic_json>>>;
20355 
20358  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
20359 
20362  using string_t = StringType;
20363 
20366  using boolean_t = BooleanType;
20367 
20370  using number_integer_t = NumberIntegerType;
20371 
20374  using number_unsigned_t = NumberUnsignedType;
20375 
20378  using number_float_t = NumberFloatType;
20379 
20382  using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
20383 
20387 
20389 
20390  private:
20391 
20393  template<typename T, typename... Args>
20395  static T* create(Args&& ... args)
20396  {
20397  AllocatorType<T> alloc;
20398  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
20399 
20400  auto deleter = [&](T * obj)
20401  {
20402  AllocatorTraits::deallocate(alloc, obj, 1);
20403  };
20404  std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
20405  AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
20406  JSON_ASSERT(obj != nullptr);
20407  return obj.release();
20408  }
20409 
20411  // JSON value storage //
20413 
20440  union json_value
20441  {
20443  object_t* object;
20445  array_t* array;
20447  string_t* string;
20449  binary_t* binary;
20451  boolean_t boolean;
20458 
20460  json_value() = default;
20462  json_value(boolean_t v) noexcept : boolean(v) {}
20464  json_value(number_integer_t v) noexcept : number_integer(v) {}
20466  json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
20468  json_value(number_float_t v) noexcept : number_float(v) {}
20470  json_value(value_t t)
20471  {
20472  switch (t)
20473  {
20474  case value_t::object:
20475  {
20476  object = create<object_t>();
20477  break;
20478  }
20479 
20480  case value_t::array:
20481  {
20482  array = create<array_t>();
20483  break;
20484  }
20485 
20486  case value_t::string:
20487  {
20488  string = create<string_t>("");
20489  break;
20490  }
20491 
20492  case value_t::binary:
20493  {
20494  binary = create<binary_t>();
20495  break;
20496  }
20497 
20498  case value_t::boolean:
20499  {
20500  boolean = static_cast<boolean_t>(false);
20501  break;
20502  }
20503 
20504  case value_t::number_integer:
20505  {
20506  number_integer = static_cast<number_integer_t>(0);
20507  break;
20508  }
20509 
20510  case value_t::number_unsigned:
20511  {
20512  number_unsigned = static_cast<number_unsigned_t>(0);
20513  break;
20514  }
20515 
20516  case value_t::number_float:
20517  {
20518  number_float = static_cast<number_float_t>(0.0);
20519  break;
20520  }
20521 
20522  case value_t::null:
20523  {
20524  object = nullptr; // silence warning, see #821
20525  break;
20526  }
20527 
20528  case value_t::discarded:
20529  default:
20530  {
20531  object = nullptr; // silence warning, see #821
20532  if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
20533  {
20534  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.12.0", nullptr)); // LCOV_EXCL_LINE
20535  }
20536  break;
20537  }
20538  }
20539  }
20540 
20542  json_value(const string_t& value) : string(create<string_t>(value)) {}
20543 
20545  json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
20546 
20548  json_value(const object_t& value) : object(create<object_t>(value)) {}
20549 
20551  json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
20552 
20554  json_value(const array_t& value) : array(create<array_t>(value)) {}
20555 
20557  json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
20558 
20560  json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
20561 
20563  json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
20564 
20566  json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
20567 
20569  json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
20570 
20571  void destroy(value_t t)
20572  {
20573  if (
20574  (t == value_t::object && object == nullptr) ||
20575  (t == value_t::array && array == nullptr) ||
20576  (t == value_t::string && string == nullptr) ||
20577  (t == value_t::binary && binary == nullptr)
20578  )
20579  {
20580  //not initialized (e.g. due to exception in the ctor)
20581  return;
20582  }
20583  if (t == value_t::array || t == value_t::object)
20584  {
20585  // flatten the current json_value to a heap-allocated stack
20586  std::vector<basic_json> stack;
20587 
20588  // move the top-level items to stack
20589  if (t == value_t::array)
20590  {
20591  stack.reserve(array->size());
20592  std::move(array->begin(), array->end(), std::back_inserter(stack));
20593  }
20594  else
20595  {
20596  stack.reserve(object->size());
20597  for (auto&& it : *object)
20598  {
20599  stack.push_back(std::move(it.second));
20600  }
20601  }
20602 
20603  while (!stack.empty())
20604  {
20605  // move the last item to local variable to be processed
20606  basic_json current_item(std::move(stack.back()));
20607  stack.pop_back();
20608 
20609  // if current_item is array/object, move
20610  // its children to the stack to be processed later
20611  if (current_item.is_array())
20612  {
20613  std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));
20614 
20615  current_item.m_data.m_value.array->clear();
20616  }
20617  else if (current_item.is_object())
20618  {
20619  for (auto&& it : *current_item.m_data.m_value.object)
20620  {
20621  stack.push_back(std::move(it.second));
20622  }
20623 
20624  current_item.m_data.m_value.object->clear();
20625  }
20626 
20627  // it's now safe that current_item get destructed
20628  // since it doesn't have any children
20629  }
20630  }
20631 
20632  switch (t)
20633  {
20634  case value_t::object:
20635  {
20636  AllocatorType<object_t> alloc;
20637  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
20638  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
20639  break;
20640  }
20641 
20642  case value_t::array:
20643  {
20644  AllocatorType<array_t> alloc;
20645  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
20646  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
20647  break;
20648  }
20649 
20650  case value_t::string:
20651  {
20652  AllocatorType<string_t> alloc;
20653  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
20654  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
20655  break;
20656  }
20657 
20658  case value_t::binary:
20659  {
20660  AllocatorType<binary_t> alloc;
20661  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
20662  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
20663  break;
20664  }
20665 
20666  case value_t::null:
20667  case value_t::boolean:
20668  case value_t::number_integer:
20669  case value_t::number_unsigned:
20670  case value_t::number_float:
20671  case value_t::discarded:
20672  default:
20673  {
20674  break;
20675  }
20676  }
20677  }
20678  };
20679 
20680  private:
20699  void assert_invariant(bool check_parents = true) const noexcept
20700  {
20701  JSON_ASSERT(m_data.m_type != value_t::object || m_data.m_value.object != nullptr);
20702  JSON_ASSERT(m_data.m_type != value_t::array || m_data.m_value.array != nullptr);
20703  JSON_ASSERT(m_data.m_type != value_t::string || m_data.m_value.string != nullptr);
20704  JSON_ASSERT(m_data.m_type != value_t::binary || m_data.m_value.binary != nullptr);
20705 
20706 #if JSON_DIAGNOSTICS
20707  JSON_TRY
20708  {
20709  // cppcheck-suppress assertWithSideEffect
20710  JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
20711  {
20712  return j.m_parent == this;
20713  }));
20714  }
20715  JSON_CATCH(...) {} // LCOV_EXCL_LINE
20716 #endif
20717  static_cast<void>(check_parents);
20718  }
20719 
20720  void set_parents()
20721  {
20722 #if JSON_DIAGNOSTICS
20723  switch (m_data.m_type)
20724  {
20725  case value_t::array:
20726  {
20727  for (auto& element : *m_data.m_value.array)
20728  {
20729  element.m_parent = this;
20730  }
20731  break;
20732  }
20733 
20734  case value_t::object:
20735  {
20736  for (auto& element : *m_data.m_value.object)
20737  {
20738  element.second.m_parent = this;
20739  }
20740  break;
20741  }
20742 
20743  case value_t::null:
20744  case value_t::string:
20745  case value_t::boolean:
20746  case value_t::number_integer:
20747  case value_t::number_unsigned:
20748  case value_t::number_float:
20749  case value_t::binary:
20750  case value_t::discarded:
20751  default:
20752  break;
20753  }
20754 #endif
20755  }
20756 
20757  iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
20758  {
20759 #if JSON_DIAGNOSTICS
20760  for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
20761  {
20762  (it + i)->m_parent = this;
20763  }
20764 #else
20765  static_cast<void>(count_set_parents);
20766 #endif
20767  return it;
20768  }
20769 
20770  reference set_parent(reference j, std::size_t old_capacity = detail::unknown_size())
20771  {
20772 #if JSON_DIAGNOSTICS
20773  if (old_capacity != detail::unknown_size())
20774  {
20775  // see https://github.com/nlohmann/json/issues/2838
20776  JSON_ASSERT(type() == value_t::array);
20777  if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
20778  {
20779  // capacity has changed: update all parents
20780  set_parents();
20781  return j;
20782  }
20783  }
20784 
20785  // ordered_json uses a vector internally, so pointers could have
20786  // been invalidated; see https://github.com/nlohmann/json/issues/2962
20787 #ifdef JSON_HEDLEY_MSVC_VERSION
20788 #pragma warning(push )
20789 #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
20790 #endif
20792  {
20793  set_parents();
20794  return j;
20795  }
20796 #ifdef JSON_HEDLEY_MSVC_VERSION
20797 #pragma warning( pop )
20798 #endif
20799 
20800  j.m_parent = this;
20801 #else
20802  static_cast<void>(j);
20803  static_cast<void>(old_capacity);
20804 #endif
20805  return j;
20806  }
20807 
20808  public:
20810  // JSON parser callback //
20812 
20816 
20820 
20822  // constructors //
20824 
20829 
20833  : m_data(v)
20834  {
20835  assert_invariant();
20836  }
20837 
20840  basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
20841  : basic_json(value_t::null)
20842  {
20843  assert_invariant();
20844  }
20845 
20848  template < typename CompatibleType,
20849  typename U = detail::uncvref_t<CompatibleType>,
20852  basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
20853  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
20854  std::forward<CompatibleType>(val))))
20855  {
20856  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
20857  set_parents();
20858  assert_invariant();
20859  }
20860 
20863  template < typename BasicJsonType,
20865  detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
20866  basic_json(const BasicJsonType& val)
20867 #if JSON_DIAGNOSTIC_POSITIONS
20868  : start_position(val.start_pos()),
20869  end_position(val.end_pos())
20870 #endif
20871  {
20872  using other_boolean_t = typename BasicJsonType::boolean_t;
20873  using other_number_float_t = typename BasicJsonType::number_float_t;
20874  using other_number_integer_t = typename BasicJsonType::number_integer_t;
20875  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
20876  using other_string_t = typename BasicJsonType::string_t;
20877  using other_object_t = typename BasicJsonType::object_t;
20878  using other_array_t = typename BasicJsonType::array_t;
20879  using other_binary_t = typename BasicJsonType::binary_t;
20880 
20881  switch (val.type())
20882  {
20883  case value_t::boolean:
20884  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
20885  break;
20886  case value_t::number_float:
20887  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
20888  break;
20889  case value_t::number_integer:
20890  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
20891  break;
20892  case value_t::number_unsigned:
20893  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
20894  break;
20895  case value_t::string:
20896  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
20897  break;
20898  case value_t::object:
20899  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
20900  break;
20901  case value_t::array:
20902  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
20903  break;
20904  case value_t::binary:
20905  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
20906  break;
20907  case value_t::null:
20908  *this = nullptr;
20909  break;
20910  case value_t::discarded:
20911  m_data.m_type = value_t::discarded;
20912  break;
20913  default: // LCOV_EXCL_LINE
20914  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
20915  }
20916  JSON_ASSERT(m_data.m_type == val.type());
20917 
20918  set_parents();
20919  assert_invariant();
20920  }
20921 
20925  bool type_deduction = true,
20926  value_t manual_type = value_t::array)
20927  {
20928  // check if each element is an array with two elements whose first
20929  // element is a string
20930  bool is_an_object = std::all_of(init.begin(), init.end(),
20931  [](const detail::json_ref<basic_json>& element_ref)
20932  {
20933  // The cast is to ensure op[size_type] is called, bearing in mind size_type may not be int;
20934  // (many string types can be constructed from 0 via its null-pointer guise, so we get a
20935  // broken call to op[key_type], the wrong semantics and a 4804 warning on Windows)
20936  return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[static_cast<size_type>(0)].is_string();
20937  });
20938 
20939  // adjust type if type deduction is not wanted
20940  if (!type_deduction)
20941  {
20942  // if array is wanted, do not create an object though possible
20943  if (manual_type == value_t::array)
20944  {
20945  is_an_object = false;
20946  }
20947 
20948  // if object is wanted but impossible, throw an exception
20949  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
20950  {
20951  JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
20952  }
20953  }
20954 
20955  if (is_an_object)
20956  {
20957  // the initializer list is a list of pairs -> create object
20958  m_data.m_type = value_t::object;
20959  m_data.m_value = value_t::object;
20960 
20961  for (auto& element_ref : init)
20962  {
20963  auto element = element_ref.moved_or_copied();
20964  m_data.m_value.object->emplace(
20965  std::move(*((*element.m_data.m_value.array)[0].m_data.m_value.string)),
20966  std::move((*element.m_data.m_value.array)[1]));
20967  }
20968  }
20969  else
20970  {
20971  // the initializer list describes an array -> create array
20972  m_data.m_type = value_t::array;
20973  m_data.m_value.array = create<array_t>(init.begin(), init.end());
20974  }
20975 
20976  set_parents();
20977  assert_invariant();
20978  }
20979 
20983  static basic_json binary(const typename binary_t::container_type& init)
20984  {
20985  auto res = basic_json();
20986  res.m_data.m_type = value_t::binary;
20987  res.m_data.m_value = init;
20988  return res;
20989  }
20990 
20994  static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
20995  {
20996  auto res = basic_json();
20997  res.m_data.m_type = value_t::binary;
20998  res.m_data.m_value = binary_t(init, subtype);
20999  return res;
21000  }
21001 
21005  static basic_json binary(typename binary_t::container_type&& init)
21006  {
21007  auto res = basic_json();
21008  res.m_data.m_type = value_t::binary;
21009  res.m_data.m_value = std::move(init);
21010  return res;
21011  }
21012 
21016  static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
21017  {
21018  auto res = basic_json();
21019  res.m_data.m_type = value_t::binary;
21020  res.m_data.m_value = binary_t(std::move(init), subtype);
21021  return res;
21022  }
21023 
21028  {
21029  return basic_json(init, false, value_t::array);
21030  }
21031 
21036  {
21037  return basic_json(init, false, value_t::object);
21038  }
21039 
21042  basic_json(size_type cnt, const basic_json& val):
21043  m_data{cnt, val}
21044  {
21045  set_parents();
21046  assert_invariant();
21047  }
21048 
21051  template < class InputIT, typename std::enable_if <
21052  std::is_same<InputIT, typename basic_json_t::iterator>::value ||
21053  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
21054  basic_json(InputIT first, InputIT last) // NOLINT(performance-unnecessary-value-param)
21055  {
21056  JSON_ASSERT(first.m_object != nullptr);
21057  JSON_ASSERT(last.m_object != nullptr);
21058 
21059  // make sure iterator fits the current value
21060  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21061  {
21062  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
21063  }
21064 
21065  // copy type from first iterator
21066  m_data.m_type = first.m_object->m_data.m_type;
21067 
21068  // check if iterator range is complete for primitive values
21069  switch (m_data.m_type)
21070  {
21071  case value_t::boolean:
21072  case value_t::number_float:
21073  case value_t::number_integer:
21074  case value_t::number_unsigned:
21075  case value_t::string:
21076  {
21077  if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
21078  || !last.m_it.primitive_iterator.is_end()))
21079  {
21080  JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
21081  }
21082  break;
21083  }
21084 
21085  case value_t::null:
21086  case value_t::object:
21087  case value_t::array:
21088  case value_t::binary:
21089  case value_t::discarded:
21090  default:
21091  break;
21092  }
21093 
21094  switch (m_data.m_type)
21095  {
21096  case value_t::number_integer:
21097  {
21098  m_data.m_value.number_integer = first.m_object->m_data.m_value.number_integer;
21099  break;
21100  }
21101 
21102  case value_t::number_unsigned:
21103  {
21104  m_data.m_value.number_unsigned = first.m_object->m_data.m_value.number_unsigned;
21105  break;
21106  }
21107 
21108  case value_t::number_float:
21109  {
21110  m_data.m_value.number_float = first.m_object->m_data.m_value.number_float;
21111  break;
21112  }
21113 
21114  case value_t::boolean:
21115  {
21116  m_data.m_value.boolean = first.m_object->m_data.m_value.boolean;
21117  break;
21118  }
21119 
21120  case value_t::string:
21121  {
21122  m_data.m_value = *first.m_object->m_data.m_value.string;
21123  break;
21124  }
21125 
21126  case value_t::object:
21127  {
21128  m_data.m_value.object = create<object_t>(first.m_it.object_iterator,
21129  last.m_it.object_iterator);
21130  break;
21131  }
21132 
21133  case value_t::array:
21134  {
21135  m_data.m_value.array = create<array_t>(first.m_it.array_iterator,
21136  last.m_it.array_iterator);
21137  break;
21138  }
21139 
21140  case value_t::binary:
21141  {
21142  m_data.m_value = *first.m_object->m_data.m_value.binary;
21143  break;
21144  }
21145 
21146  case value_t::null:
21147  case value_t::discarded:
21148  default:
21149  JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
21150  }
21151 
21152  set_parents();
21153  assert_invariant();
21154  }
21155 
21157  // other constructors and destructor //
21159 
21160  template<typename JsonRef,
21162  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
21163  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
21164 
21167  basic_json(const basic_json& other)
21168  : json_base_class_t(other)
21170  , start_position(other.start_position)
21171  , end_position(other.end_position)
21172 #endif
21173  {
21174  m_data.m_type = other.m_data.m_type;
21175  // check of passed value is valid
21176  other.assert_invariant();
21177 
21178  switch (m_data.m_type)
21179  {
21180  case value_t::object:
21181  {
21182  m_data.m_value = *other.m_data.m_value.object;
21183  break;
21184  }
21185 
21186  case value_t::array:
21187  {
21188  m_data.m_value = *other.m_data.m_value.array;
21189  break;
21190  }
21191 
21192  case value_t::string:
21193  {
21194  m_data.m_value = *other.m_data.m_value.string;
21195  break;
21196  }
21197 
21198  case value_t::boolean:
21199  {
21200  m_data.m_value = other.m_data.m_value.boolean;
21201  break;
21202  }
21203 
21204  case value_t::number_integer:
21205  {
21206  m_data.m_value = other.m_data.m_value.number_integer;
21207  break;
21208  }
21209 
21210  case value_t::number_unsigned:
21211  {
21212  m_data.m_value = other.m_data.m_value.number_unsigned;
21213  break;
21214  }
21215 
21216  case value_t::number_float:
21217  {
21218  m_data.m_value = other.m_data.m_value.number_float;
21219  break;
21220  }
21221 
21222  case value_t::binary:
21223  {
21224  m_data.m_value = *other.m_data.m_value.binary;
21225  break;
21226  }
21227 
21228  case value_t::null:
21229  case value_t::discarded:
21230  default:
21231  break;
21232  }
21233 
21234  set_parents();
21235  assert_invariant();
21236  }
21237 
21240  basic_json(basic_json&& other) noexcept
21241  : json_base_class_t(std::forward<json_base_class_t>(other)),
21242  m_data(std::move(other.m_data)) // cppcheck-suppress[accessForwarded] TODO check
21243 #if JSON_DIAGNOSTIC_POSITIONS
21244  , start_position(other.start_position) // cppcheck-suppress[accessForwarded] TODO check
21245  , end_position(other.end_position) // cppcheck-suppress[accessForwarded] TODO check
21246 #endif
21247  {
21248  // check that passed value is valid
21249  other.assert_invariant(false); // cppcheck-suppress[accessForwarded]
21250 
21251  // invalidate payload
21252  other.m_data.m_type = value_t::null;
21253  other.m_data.m_value = {};
21254 
21255 #if JSON_DIAGNOSTIC_POSITIONS
21256  other.start_position = std::string::npos;
21257  other.end_position = std::string::npos;
21258 #endif
21259 
21260  set_parents();
21261  assert_invariant();
21262  }
21263 
21266  basic_json& operator=(basic_json other) noexcept (
21267  std::is_nothrow_move_constructible<value_t>::value&&
21268  std::is_nothrow_move_assignable<value_t>::value&&
21269  std::is_nothrow_move_constructible<json_value>::value&&
21270  std::is_nothrow_move_assignable<json_value>::value&&
21271  std::is_nothrow_move_assignable<json_base_class_t>::value
21272  )
21273  {
21274  // check that passed value is valid
21275  other.assert_invariant();
21276 
21277  using std::swap;
21278  swap(m_data.m_type, other.m_data.m_type);
21279  swap(m_data.m_value, other.m_data.m_value);
21280 
21281 #if JSON_DIAGNOSTIC_POSITIONS
21282  swap(start_position, other.start_position);
21283  swap(end_position, other.end_position);
21284 #endif
21285 
21286  json_base_class_t::operator=(std::move(other));
21287 
21288  set_parents();
21289  assert_invariant();
21290  return *this;
21291  }
21292 
21295  ~basic_json() noexcept
21296  {
21297  assert_invariant(false);
21298  }
21299 
21301 
21302  public:
21304  // object inspection //
21306 
21310 
21313  string_t dump(const int indent = -1,
21314  const char indent_char = ' ',
21315  const bool ensure_ascii = false,
21316  const error_handler_t error_handler = error_handler_t::strict) const
21317  {
21318  string_t result;
21319  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
21320 
21321  if (indent >= 0)
21322  {
21323  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
21324  }
21325  else
21326  {
21327  s.dump(*this, false, ensure_ascii, 0);
21328  }
21329 
21330  return result;
21331  }
21332 
21335  constexpr value_t type() const noexcept
21336  {
21337  return m_data.m_type;
21338  }
21339 
21342  constexpr bool is_primitive() const noexcept
21343  {
21344  return is_null() || is_string() || is_boolean() || is_number() || is_binary();
21345  }
21346 
21349  constexpr bool is_structured() const noexcept
21350  {
21351  return is_array() || is_object();
21352  }
21353 
21356  constexpr bool is_null() const noexcept
21357  {
21358  return m_data.m_type == value_t::null;
21359  }
21360 
21363  constexpr bool is_boolean() const noexcept
21364  {
21365  return m_data.m_type == value_t::boolean;
21366  }
21367 
21370  constexpr bool is_number() const noexcept
21371  {
21372  return is_number_integer() || is_number_float();
21373  }
21374 
21377  constexpr bool is_number_integer() const noexcept
21378  {
21379  return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;
21380  }
21381 
21384  constexpr bool is_number_unsigned() const noexcept
21385  {
21386  return m_data.m_type == value_t::number_unsigned;
21387  }
21388 
21391  constexpr bool is_number_float() const noexcept
21392  {
21393  return m_data.m_type == value_t::number_float;
21394  }
21395 
21398  constexpr bool is_object() const noexcept
21399  {
21400  return m_data.m_type == value_t::object;
21401  }
21402 
21405  constexpr bool is_array() const noexcept
21406  {
21407  return m_data.m_type == value_t::array;
21408  }
21409 
21412  constexpr bool is_string() const noexcept
21413  {
21414  return m_data.m_type == value_t::string;
21415  }
21416 
21419  constexpr bool is_binary() const noexcept
21420  {
21421  return m_data.m_type == value_t::binary;
21422  }
21423 
21426  constexpr bool is_discarded() const noexcept
21427  {
21428  return m_data.m_type == value_t::discarded;
21429  }
21430 
21433  constexpr operator value_t() const noexcept
21434  {
21435  return m_data.m_type;
21436  }
21437 
21439 
21440  private:
21442  // value access //
21444 
21446  boolean_t get_impl(boolean_t* /*unused*/) const
21447  {
21448  if (JSON_HEDLEY_LIKELY(is_boolean()))
21449  {
21450  return m_data.m_value.boolean;
21451  }
21452 
21453  JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
21454  }
21455 
21457  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
21458  {
21459  return is_object() ? m_data.m_value.object : nullptr;
21460  }
21461 
21463  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
21464  {
21465  return is_object() ? m_data.m_value.object : nullptr;
21466  }
21467 
21469  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
21470  {
21471  return is_array() ? m_data.m_value.array : nullptr;
21472  }
21473 
21475  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
21476  {
21477  return is_array() ? m_data.m_value.array : nullptr;
21478  }
21479 
21481  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
21482  {
21483  return is_string() ? m_data.m_value.string : nullptr;
21484  }
21485 
21487  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
21488  {
21489  return is_string() ? m_data.m_value.string : nullptr;
21490  }
21491 
21493  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
21494  {
21495  return is_boolean() ? &m_data.m_value.boolean : nullptr;
21496  }
21497 
21499  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
21500  {
21501  return is_boolean() ? &m_data.m_value.boolean : nullptr;
21502  }
21503 
21505  number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
21506  {
21507  return m_data.m_type == value_t::number_integer ? &m_data.m_value.number_integer : nullptr;
21508  }
21509 
21511  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
21512  {
21513  return m_data.m_type == value_t::number_integer ? &m_data.m_value.number_integer : nullptr;
21514  }
21515 
21517  number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
21518  {
21519  return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
21520  }
21521 
21523  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
21524  {
21525  return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
21526  }
21527 
21529  number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
21530  {
21531  return is_number_float() ? &m_data.m_value.number_float : nullptr;
21532  }
21533 
21535  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
21536  {
21537  return is_number_float() ? &m_data.m_value.number_float : nullptr;
21538  }
21539 
21541  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
21542  {
21543  return is_binary() ? m_data.m_value.binary : nullptr;
21544  }
21545 
21547  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
21548  {
21549  return is_binary() ? m_data.m_value.binary : nullptr;
21550  }
21551 
21563  template<typename ReferenceType, typename ThisType>
21564  static ReferenceType get_ref_impl(ThisType& obj)
21565  {
21566  // delegate the call to get_ptr<>()
21567  auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
21568 
21569  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
21570  {
21571  return *ptr;
21572  }
21573 
21574  JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
21575  }
21576 
21577  public:
21581 
21584  template<typename PointerType, typename std::enable_if<
21585  std::is_pointer<PointerType>::value, int>::type = 0>
21586  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
21587  {
21588  // delegate the call to get_impl_ptr<>()
21589  return get_impl_ptr(static_cast<PointerType>(nullptr));
21590  }
21591 
21594  template < typename PointerType, typename std::enable_if <
21595  std::is_pointer<PointerType>::value&&
21596  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
21597  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
21598  {
21599  // delegate the call to get_impl_ptr<>() const
21600  return get_impl_ptr(static_cast<PointerType>(nullptr));
21601  }
21602 
21603  private:
21642  template < typename ValueType,
21646  int > = 0 >
21647  ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
21648  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
21649  {
21650  auto ret = ValueType();
21652  return ret;
21653  }
21654 
21685  template < typename ValueType,
21688  int > = 0 >
21689  ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
21690  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
21691  {
21693  }
21694 
21710  template < typename BasicJsonType,
21713  int > = 0 >
21714  BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
21715  {
21716  return *this;
21717  }
21718 
21733  template<typename BasicJsonType,
21735  std::is_same<BasicJsonType, basic_json_t>::value,
21736  int> = 0>
21737  basic_json get_impl(detail::priority_tag<3> /*unused*/) const
21738  {
21739  return *this;
21740  }
21741 
21746  template<typename PointerType,
21748  std::is_pointer<PointerType>::value,
21749  int> = 0>
21750  constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
21751  -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
21752  {
21753  // delegate the call to get_ptr
21754  return get_ptr<PointerType>();
21755  }
21756 
21757  public:
21781  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
21782 #if defined(JSON_HAS_CPP_14)
21783  constexpr
21784 #endif
21785  auto get() const noexcept(
21786  noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
21787  -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
21788  {
21789  // we cannot static_assert on ValueTypeCV being non-const, because
21790  // there is support for get<const basic_json_t>(), which is why we
21791  // still need the uncvref
21792  static_assert(!std::is_reference<ValueTypeCV>::value,
21793  "get() cannot be used with reference types, you might want to use get_ref()");
21794  return get_impl<ValueType>(detail::priority_tag<4> {});
21795  }
21796 
21824  template<typename PointerType, typename std::enable_if<
21825  std::is_pointer<PointerType>::value, int>::type = 0>
21826  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
21827  {
21828  // delegate the call to get_ptr
21829  return get_ptr<PointerType>();
21830  }
21831 
21834  template < typename ValueType,
21838  int > = 0 >
21839  ValueType & get_to(ValueType& v) const noexcept(noexcept(
21840  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
21841  {
21843  return v;
21844  }
21845 
21846  // specialization to allow calling get_to with a basic_json value
21847  // see https://github.com/nlohmann/json/issues/2175
21848  template<typename ValueType,
21851  int> = 0>
21852  ValueType & get_to(ValueType& v) const
21853  {
21854  v = *this;
21855  return v;
21856  }
21857 
21858  template <
21859  typename T, std::size_t N,
21860  typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21863  Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21864  noexcept(noexcept(JSONSerializer<Array>::from_json(
21865  std::declval<const basic_json_t&>(), v)))
21866  {
21868  return v;
21869  }
21870 
21873  template<typename ReferenceType, typename std::enable_if<
21874  std::is_reference<ReferenceType>::value, int>::type = 0>
21875  ReferenceType get_ref()
21876  {
21877  // delegate call to get_ref_impl
21878  return get_ref_impl<ReferenceType>(*this);
21879  }
21880 
21883  template < typename ReferenceType, typename std::enable_if <
21884  std::is_reference<ReferenceType>::value&&
21885  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
21886  ReferenceType get_ref() const
21887  {
21888  // delegate call to get_ref_impl
21889  return get_ref_impl<ReferenceType>(*this);
21890  }
21891 
21921  template < typename ValueType, typename std::enable_if <
21929 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
21931 #endif
21932 #if defined(JSON_HAS_CPP_17) && JSON_HAS_STATIC_RTTI
21934 #endif
21936  >::value, int >::type = 0 >
21937  JSON_EXPLICIT operator ValueType() const
21938  {
21939  // delegate the call to get<>() const
21940  return get<ValueType>();
21941  }
21942 
21946  {
21947  if (!is_binary())
21948  {
21949  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21950  }
21951 
21952  return *get_ptr<binary_t*>();
21953  }
21954 
21957  const binary_t& get_binary() const
21958  {
21959  if (!is_binary())
21960  {
21961  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21962  }
21963 
21964  return *get_ptr<const binary_t*>();
21965  }
21966 
21968 
21970  // element access //
21972 
21976 
21980  {
21981  // at only works for arrays
21982  if (JSON_HEDLEY_LIKELY(is_array()))
21983  {
21984  JSON_TRY
21985  {
21986  return set_parent(m_data.m_value.array->at(idx));
21987  }
21988  JSON_CATCH (std::out_of_range&)
21989  {
21990  // create better exception explanation
21991  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21992  } // cppcheck-suppress[missingReturn]
21993  }
21994  else
21995  {
21996  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21997  }
21998  }
21999 
22003  {
22004  // at only works for arrays
22005  if (JSON_HEDLEY_LIKELY(is_array()))
22006  {
22007  JSON_TRY
22008  {
22009  return m_data.m_value.array->at(idx);
22010  }
22011  JSON_CATCH (std::out_of_range&)
22012  {
22013  // create better exception explanation
22014  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
22015  } // cppcheck-suppress[missingReturn]
22016  }
22017  else
22018  {
22019  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
22020  }
22021  }
22022 
22025  reference at(const typename object_t::key_type& key)
22026  {
22027  // at only works for objects
22028  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22029  {
22030  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
22031  }
22032 
22033  auto it = m_data.m_value.object->find(key);
22034  if (it == m_data.m_value.object->end())
22035  {
22036  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
22037  }
22038  return set_parent(it->second);
22039  }
22040 
22043  template<class KeyType, detail::enable_if_t<
22045  reference at(KeyType && key)
22046  {
22047  // at only works for objects
22048  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22049  {
22050  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
22051  }
22052 
22053  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
22054  if (it == m_data.m_value.object->end())
22055  {
22056  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
22057  }
22058  return set_parent(it->second);
22059  }
22060 
22063  const_reference at(const typename object_t::key_type& key) const
22064  {
22065  // at only works for objects
22066  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22067  {
22068  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
22069  }
22070 
22071  auto it = m_data.m_value.object->find(key);
22072  if (it == m_data.m_value.object->end())
22073  {
22074  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
22075  }
22076  return it->second;
22077  }
22078 
22081  template<class KeyType, detail::enable_if_t<
22083  const_reference at(KeyType && key) const
22084  {
22085  // at only works for objects
22086  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22087  {
22088  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
22089  }
22090 
22091  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
22092  if (it == m_data.m_value.object->end())
22093  {
22094  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
22095  }
22096  return it->second;
22097  }
22098 
22102  {
22103  // implicitly convert null value to an empty array
22104  if (is_null())
22105  {
22106  m_data.m_type = value_t::array;
22107  m_data.m_value.array = create<array_t>();
22108  assert_invariant();
22109  }
22110 
22111  // operator[] only works for arrays
22112  if (JSON_HEDLEY_LIKELY(is_array()))
22113  {
22114  // fill up array with null values if given idx is outside range
22115  if (idx >= m_data.m_value.array->size())
22116  {
22117 #if JSON_DIAGNOSTICS
22118  // remember array size & capacity before resizing
22119  const auto old_size = m_data.m_value.array->size();
22120  const auto old_capacity = m_data.m_value.array->capacity();
22121 #endif
22122  m_data.m_value.array->resize(idx + 1);
22123 
22124 #if JSON_DIAGNOSTICS
22125  if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
22126  {
22127  // capacity has changed: update all parents
22128  set_parents();
22129  }
22130  else
22131  {
22132  // set parent for values added above
22133  set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
22134  }
22135 #endif
22136  assert_invariant();
22137  }
22138 
22139  return m_data.m_value.array->operator[](idx);
22140  }
22141 
22142  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
22143  }
22144 
22148  {
22149  // const operator[] only works for arrays
22150  if (JSON_HEDLEY_LIKELY(is_array()))
22151  {
22152  return m_data.m_value.array->operator[](idx);
22153  }
22154 
22155  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
22156  }
22157 
22160  reference operator[](typename object_t::key_type key) // NOLINT(performance-unnecessary-value-param)
22161  {
22162  // implicitly convert null value to an empty object
22163  if (is_null())
22164  {
22165  m_data.m_type = value_t::object;
22166  m_data.m_value.object = create<object_t>();
22167  assert_invariant();
22168  }
22169 
22170  // operator[] only works for objects
22171  if (JSON_HEDLEY_LIKELY(is_object()))
22172  {
22173  auto result = m_data.m_value.object->emplace(std::move(key), nullptr);
22174  return set_parent(result.first->second);
22175  }
22176 
22177  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
22178  }
22179 
22182  const_reference operator[](const typename object_t::key_type& key) const
22183  {
22184  // const operator[] only works for objects
22185  if (JSON_HEDLEY_LIKELY(is_object()))
22186  {
22187  auto it = m_data.m_value.object->find(key);
22188  JSON_ASSERT(it != m_data.m_value.object->end());
22189  return it->second;
22190  }
22191 
22192  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
22193  }
22194 
22195  // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
22196  // (they seemingly cannot be constrained to resolve the ambiguity)
22197  template<typename T>
22199  {
22200  return operator[](typename object_t::key_type(key));
22201  }
22202 
22203  template<typename T>
22205  {
22206  return operator[](typename object_t::key_type(key));
22207  }
22208 
22211  template<class KeyType, detail::enable_if_t<
22214  {
22215  // implicitly convert null value to an empty object
22216  if (is_null())
22217  {
22218  m_data.m_type = value_t::object;
22219  m_data.m_value.object = create<object_t>();
22220  assert_invariant();
22221  }
22222 
22223  // operator[] only works for objects
22224  if (JSON_HEDLEY_LIKELY(is_object()))
22225  {
22226  auto result = m_data.m_value.object->emplace(std::forward<KeyType>(key), nullptr);
22227  return set_parent(result.first->second);
22228  }
22229 
22230  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
22231  }
22232 
22235  template<class KeyType, detail::enable_if_t<
22237  const_reference operator[](KeyType && key) const
22238  {
22239  // const operator[] only works for objects
22240  if (JSON_HEDLEY_LIKELY(is_object()))
22241  {
22242  auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
22243  JSON_ASSERT(it != m_data.m_value.object->end());
22244  return it->second;
22245  }
22246 
22247  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
22248  }
22249 
22250  private:
22251  template<typename KeyType>
22252  using is_comparable_with_object_key = detail::is_comparable <
22253  object_comparator_t, const typename object_t::key_type&, KeyType >;
22254 
22255  template<typename ValueType>
22256  using value_return_type = std::conditional <
22258  string_t, typename std::decay<ValueType>::type >;
22259 
22260  public:
22263  template < class ValueType, detail::enable_if_t <
22266  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22267  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
22268  {
22269  // value only works for objects
22270  if (JSON_HEDLEY_LIKELY(is_object()))
22271  {
22272  // if key is found, return value and given default value otherwise
22273  const auto it = find(key);
22274  if (it != end())
22275  {
22276  return it->template get<ValueType>();
22277  }
22278 
22279  return default_value;
22280  }
22281 
22282  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
22283  }
22284 
22287  template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
22291  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22292  ReturnType value(const typename object_t::key_type& key, ValueType && default_value) const
22293  {
22294  // value only works for objects
22295  if (JSON_HEDLEY_LIKELY(is_object()))
22296  {
22297  // if key is found, return value and given default value otherwise
22298  const auto it = find(key);
22299  if (it != end())
22300  {
22301  return it->template get<ReturnType>();
22302  }
22303 
22304  return std::forward<ValueType>(default_value);
22305  }
22306 
22307  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
22308  }
22309 
22312  template < class ValueType, class KeyType, detail::enable_if_t <
22315  && is_comparable_with_object_key<KeyType>::value
22317  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22318  ValueType value(KeyType && key, const ValueType& default_value) const
22319  {
22320  // value only works for objects
22321  if (JSON_HEDLEY_LIKELY(is_object()))
22322  {
22323  // if key is found, return value and given default value otherwise
22324  const auto it = find(std::forward<KeyType>(key));
22325  if (it != end())
22326  {
22327  return it->template get<ValueType>();
22328  }
22329 
22330  return default_value;
22331  }
22332 
22333  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
22334  }
22335 
22338  template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type,
22342  && is_comparable_with_object_key<KeyType>::value
22344  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22345  ReturnType value(KeyType && key, ValueType && default_value) const
22346  {
22347  // value only works for objects
22348  if (JSON_HEDLEY_LIKELY(is_object()))
22349  {
22350  // if key is found, return value and given default value otherwise
22351  const auto it = find(std::forward<KeyType>(key));
22352  if (it != end())
22353  {
22354  return it->template get<ReturnType>();
22355  }
22356 
22357  return std::forward<ValueType>(default_value);
22358  }
22359 
22360  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
22361  }
22362 
22365  template < class ValueType, detail::enable_if_t <
22367  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22368  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
22369  {
22370  // value only works for objects
22371  if (JSON_HEDLEY_LIKELY(is_object()))
22372  {
22373  // if pointer resolves a value, return it or use default value
22374  JSON_TRY
22375  {
22376  return ptr.get_checked(this).template get<ValueType>();
22377  }
22379  {
22380  return default_value;
22381  }
22382  }
22383 
22384  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
22385  }
22386 
22389  template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
22392  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22393  ReturnType value(const json_pointer& ptr, ValueType && default_value) const
22394  {
22395  // value only works for objects
22396  if (JSON_HEDLEY_LIKELY(is_object()))
22397  {
22398  // if pointer resolves a value, return it or use default value
22399  JSON_TRY
22400  {
22401  return ptr.get_checked(this).template get<ReturnType>();
22402  }
22404  {
22405  return std::forward<ValueType>(default_value);
22406  }
22407  }
22408 
22409  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
22410  }
22411 
22412  template < class ValueType, class BasicJsonType, detail::enable_if_t <
22415  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22416  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
22417  ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
22418  {
22419  return value(ptr.convert(), default_value);
22420  }
22421 
22422  template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,
22426  && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
22427  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
22428  ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value) const
22429  {
22430  return value(ptr.convert(), std::forward<ValueType>(default_value));
22431  }
22432 
22435  reference front()
22436  {
22437  return *begin();
22438  }
22439 
22443  {
22444  return *cbegin();
22445  }
22446 
22450  {
22451  auto tmp = end();
22452  --tmp;
22453  return *tmp;
22454  }
22455 
22459  {
22460  auto tmp = cend();
22461  --tmp;
22462  return *tmp;
22463  }
22464 
22467  template < class IteratorType, detail::enable_if_t <
22468  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
22469  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
22470  IteratorType erase(IteratorType pos) // NOLINT(performance-unnecessary-value-param)
22471  {
22472  // make sure iterator fits the current value
22473  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
22474  {
22475  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22476  }
22477 
22478  IteratorType result = end();
22479 
22480  switch (m_data.m_type)
22481  {
22482  case value_t::boolean:
22483  case value_t::number_float:
22484  case value_t::number_integer:
22485  case value_t::number_unsigned:
22486  case value_t::string:
22487  case value_t::binary:
22488  {
22489  if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
22490  {
22491  JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
22492  }
22493 
22494  if (is_string())
22495  {
22496  AllocatorType<string_t> alloc;
22497  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
22498  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
22499  m_data.m_value.string = nullptr;
22500  }
22501  else if (is_binary())
22502  {
22503  AllocatorType<binary_t> alloc;
22504  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
22505  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
22506  m_data.m_value.binary = nullptr;
22507  }
22508 
22509  m_data.m_type = value_t::null;
22510  assert_invariant();
22511  break;
22512  }
22513 
22514  case value_t::object:
22515  {
22516  result.m_it.object_iterator = m_data.m_value.object->erase(pos.m_it.object_iterator);
22517  break;
22518  }
22519 
22520  case value_t::array:
22521  {
22522  result.m_it.array_iterator = m_data.m_value.array->erase(pos.m_it.array_iterator);
22523  break;
22524  }
22525 
22526  case value_t::null:
22527  case value_t::discarded:
22528  default:
22529  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
22530  }
22531 
22532  return result;
22533  }
22534 
22537  template < class IteratorType, detail::enable_if_t <
22538  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
22539  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
22540  IteratorType erase(IteratorType first, IteratorType last) // NOLINT(performance-unnecessary-value-param)
22541  {
22542  // make sure iterator fits the current value
22543  if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
22544  {
22545  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
22546  }
22547 
22548  IteratorType result = end();
22549 
22550  switch (m_data.m_type)
22551  {
22552  case value_t::boolean:
22553  case value_t::number_float:
22554  case value_t::number_integer:
22555  case value_t::number_unsigned:
22556  case value_t::string:
22557  case value_t::binary:
22558  {
22559  if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
22560  || !last.m_it.primitive_iterator.is_end()))
22561  {
22562  JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
22563  }
22564 
22565  if (is_string())
22566  {
22567  AllocatorType<string_t> alloc;
22568  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
22569  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
22570  m_data.m_value.string = nullptr;
22571  }
22572  else if (is_binary())
22573  {
22574  AllocatorType<binary_t> alloc;
22575  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
22576  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
22577  m_data.m_value.binary = nullptr;
22578  }
22579 
22580  m_data.m_type = value_t::null;
22581  assert_invariant();
22582  break;
22583  }
22584 
22585  case value_t::object:
22586  {
22587  result.m_it.object_iterator = m_data.m_value.object->erase(first.m_it.object_iterator,
22588  last.m_it.object_iterator);
22589  break;
22590  }
22591 
22592  case value_t::array:
22593  {
22594  result.m_it.array_iterator = m_data.m_value.array->erase(first.m_it.array_iterator,
22595  last.m_it.array_iterator);
22596  break;
22597  }
22598 
22599  case value_t::null:
22600  case value_t::discarded:
22601  default:
22602  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
22603  }
22604 
22605  return result;
22606  }
22607 
22608  private:
22609  template < typename KeyType, detail::enable_if_t <
22611  size_type erase_internal(KeyType && key)
22612  {
22613  // this erase only works for objects
22614  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22615  {
22616  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
22617  }
22618 
22619  return m_data.m_value.object->erase(std::forward<KeyType>(key));
22620  }
22621 
22622  template < typename KeyType, detail::enable_if_t <
22624  size_type erase_internal(KeyType && key)
22625  {
22626  // this erase only works for objects
22627  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22628  {
22629  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
22630  }
22631 
22632  const auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
22633  if (it != m_data.m_value.object->end())
22634  {
22635  m_data.m_value.object->erase(it);
22636  return 1;
22637  }
22638  return 0;
22639  }
22640 
22641  public:
22642 
22645  size_type erase(const typename object_t::key_type& key)
22646  {
22647  // the indirection via erase_internal() is added to avoid making this
22648  // function a template and thus de-rank it during overload resolution
22649  return erase_internal(key);
22650  }
22651 
22654  template<class KeyType, detail::enable_if_t<
22656  size_type erase(KeyType && key)
22657  {
22658  return erase_internal(std::forward<KeyType>(key));
22659  }
22660 
22663  void erase(const size_type idx)
22664  {
22665  // this erase only works for arrays
22666  if (JSON_HEDLEY_LIKELY(is_array()))
22667  {
22668  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
22669  {
22670  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
22671  }
22672 
22673  m_data.m_value.array->erase(m_data.m_value.array->begin() + static_cast<difference_type>(idx));
22674  }
22675  else
22676  {
22677  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
22678  }
22679  }
22680 
22682 
22684  // lookup //
22686 
22689 
22692  iterator find(const typename object_t::key_type& key)
22693  {
22694  auto result = end();
22695 
22696  if (is_object())
22697  {
22698  result.m_it.object_iterator = m_data.m_value.object->find(key);
22699  }
22700 
22701  return result;
22702  }
22703 
22706  const_iterator find(const typename object_t::key_type& key) const
22707  {
22708  auto result = cend();
22709 
22710  if (is_object())
22711  {
22712  result.m_it.object_iterator = m_data.m_value.object->find(key);
22713  }
22714 
22715  return result;
22716  }
22717 
22720  template<class KeyType, detail::enable_if_t<
22722  iterator find(KeyType && key)
22723  {
22724  auto result = end();
22725 
22726  if (is_object())
22727  {
22728  result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
22729  }
22730 
22731  return result;
22732  }
22733 
22736  template<class KeyType, detail::enable_if_t<
22738  const_iterator find(KeyType && key) const
22739  {
22740  auto result = cend();
22741 
22742  if (is_object())
22743  {
22744  result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
22745  }
22746 
22747  return result;
22748  }
22749 
22752  size_type count(const typename object_t::key_type& key) const
22753  {
22754  // return 0 for all nonobject types
22755  return is_object() ? m_data.m_value.object->count(key) : 0;
22756  }
22757 
22760  template<class KeyType, detail::enable_if_t<
22762  size_type count(KeyType && key) const
22763  {
22764  // return 0 for all nonobject types
22765  return is_object() ? m_data.m_value.object->count(std::forward<KeyType>(key)) : 0;
22766  }
22767 
22770  bool contains(const typename object_t::key_type& key) const
22771  {
22772  return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();
22773  }
22774 
22777  template<class KeyType, detail::enable_if_t<
22779  bool contains(KeyType && key) const
22780  {
22781  return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();
22782  }
22783 
22786  bool contains(const json_pointer& ptr) const
22787  {
22788  return ptr.contains(this);
22789  }
22790 
22791  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
22792  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
22793  bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
22794  {
22795  return ptr.contains(this);
22796  }
22797 
22799 
22801  // iterators //
22803 
22806 
22809  iterator begin() noexcept
22810  {
22811  iterator result(this);
22812  result.set_begin();
22813  return result;
22814  }
22815 
22818  const_iterator begin() const noexcept
22819  {
22820  return cbegin();
22821  }
22822 
22825  const_iterator cbegin() const noexcept
22826  {
22827  const_iterator result(this);
22828  result.set_begin();
22829  return result;
22830  }
22831 
22834  iterator end() noexcept
22835  {
22836  iterator result(this);
22837  result.set_end();
22838  return result;
22839  }
22840 
22843  const_iterator end() const noexcept
22844  {
22845  return cend();
22846  }
22847 
22850  const_iterator cend() const noexcept
22851  {
22852  const_iterator result(this);
22853  result.set_end();
22854  return result;
22855  }
22856 
22859  reverse_iterator rbegin() noexcept
22860  {
22861  return reverse_iterator(end());
22862  }
22863 
22866  const_reverse_iterator rbegin() const noexcept
22867  {
22868  return crbegin();
22869  }
22870 
22873  reverse_iterator rend() noexcept
22874  {
22875  return reverse_iterator(begin());
22876  }
22877 
22880  const_reverse_iterator rend() const noexcept
22881  {
22882  return crend();
22883  }
22884 
22887  const_reverse_iterator crbegin() const noexcept
22888  {
22889  return const_reverse_iterator(cend());
22890  }
22891 
22894  const_reverse_iterator crend() const noexcept
22895  {
22896  return const_reverse_iterator(cbegin());
22897  }
22898 
22899  public:
22905  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22906  static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22907  {
22908  return ref.items();
22909  }
22910 
22916  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22917  static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22918  {
22919  return ref.items();
22920  }
22921 
22924  iteration_proxy<iterator> items() noexcept
22925  {
22926  return iteration_proxy<iterator>(*this);
22927  }
22928 
22931  iteration_proxy<const_iterator> items() const noexcept
22932  {
22933  return iteration_proxy<const_iterator>(*this);
22934  }
22935 
22937 
22939  // capacity //
22941 
22944 
22947  bool empty() const noexcept
22948  {
22949  switch (m_data.m_type)
22950  {
22951  case value_t::null:
22952  {
22953  // null values are empty
22954  return true;
22955  }
22956 
22957  case value_t::array:
22958  {
22959  // delegate call to array_t::empty()
22960  return m_data.m_value.array->empty();
22961  }
22962 
22963  case value_t::object:
22964  {
22965  // delegate call to object_t::empty()
22966  return m_data.m_value.object->empty();
22967  }
22968 
22969  case value_t::string:
22970  case value_t::boolean:
22971  case value_t::number_integer:
22972  case value_t::number_unsigned:
22973  case value_t::number_float:
22974  case value_t::binary:
22975  case value_t::discarded:
22976  default:
22977  {
22978  // all other types are nonempty
22979  return false;
22980  }
22981  }
22982  }
22983 
22986  size_type size() const noexcept
22987  {
22988  switch (m_data.m_type)
22989  {
22990  case value_t::null:
22991  {
22992  // null values are empty
22993  return 0;
22994  }
22995 
22996  case value_t::array:
22997  {
22998  // delegate call to array_t::size()
22999  return m_data.m_value.array->size();
23000  }
23001 
23002  case value_t::object:
23003  {
23004  // delegate call to object_t::size()
23005  return m_data.m_value.object->size();
23006  }
23007 
23008  case value_t::string:
23009  case value_t::boolean:
23010  case value_t::number_integer:
23011  case value_t::number_unsigned:
23012  case value_t::number_float:
23013  case value_t::binary:
23014  case value_t::discarded:
23015  default:
23016  {
23017  // all other types have size 1
23018  return 1;
23019  }
23020  }
23021  }
23022 
23025  size_type max_size() const noexcept
23026  {
23027  switch (m_data.m_type)
23028  {
23029  case value_t::array:
23030  {
23031  // delegate call to array_t::max_size()
23032  return m_data.m_value.array->max_size();
23033  }
23034 
23035  case value_t::object:
23036  {
23037  // delegate call to object_t::max_size()
23038  return m_data.m_value.object->max_size();
23039  }
23040 
23041  case value_t::null:
23042  case value_t::string:
23043  case value_t::boolean:
23044  case value_t::number_integer:
23045  case value_t::number_unsigned:
23046  case value_t::number_float:
23047  case value_t::binary:
23048  case value_t::discarded:
23049  default:
23050  {
23051  // all other types have max_size() == size()
23052  return size();
23053  }
23054  }
23055  }
23056 
23058 
23060  // modifiers //
23062 
23065 
23068  void clear() noexcept
23069  {
23070  switch (m_data.m_type)
23071  {
23072  case value_t::number_integer:
23073  {
23074  m_data.m_value.number_integer = 0;
23075  break;
23076  }
23077 
23078  case value_t::number_unsigned:
23079  {
23080  m_data.m_value.number_unsigned = 0;
23081  break;
23082  }
23083 
23084  case value_t::number_float:
23085  {
23086  m_data.m_value.number_float = 0.0;
23087  break;
23088  }
23089 
23090  case value_t::boolean:
23091  {
23092  m_data.m_value.boolean = false;
23093  break;
23094  }
23095 
23096  case value_t::string:
23097  {
23098  m_data.m_value.string->clear();
23099  break;
23100  }
23101 
23102  case value_t::binary:
23103  {
23104  m_data.m_value.binary->clear();
23105  break;
23106  }
23107 
23108  case value_t::array:
23109  {
23110  m_data.m_value.array->clear();
23111  break;
23112  }
23113 
23114  case value_t::object:
23115  {
23116  m_data.m_value.object->clear();
23117  break;
23118  }
23119 
23120  case value_t::null:
23121  case value_t::discarded:
23122  default:
23123  break;
23124  }
23125  }
23126 
23129  void push_back(basic_json&& val)
23130  {
23131  // push_back only works for null objects or arrays
23132  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23133  {
23134  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
23135  }
23136 
23137  // transform null object into an array
23138  if (is_null())
23139  {
23140  m_data.m_type = value_t::array;
23141  m_data.m_value = value_t::array;
23142  assert_invariant();
23143  }
23144 
23145  // add element to array (move semantics)
23146  const auto old_capacity = m_data.m_value.array->capacity();
23147  m_data.m_value.array->push_back(std::move(val));
23148  set_parent(m_data.m_value.array->back(), old_capacity);
23149  // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
23150  }
23151 
23155  {
23156  push_back(std::move(val));
23157  return *this;
23158  }
23159 
23162  void push_back(const basic_json& val)
23163  {
23164  // push_back only works for null objects or arrays
23165  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23166  {
23167  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
23168  }
23169 
23170  // transform null object into an array
23171  if (is_null())
23172  {
23173  m_data.m_type = value_t::array;
23174  m_data.m_value = value_t::array;
23175  assert_invariant();
23176  }
23177 
23178  // add element to array
23179  const auto old_capacity = m_data.m_value.array->capacity();
23180  m_data.m_value.array->push_back(val);
23181  set_parent(m_data.m_value.array->back(), old_capacity);
23182  }
23183 
23187  {
23188  push_back(val);
23189  return *this;
23190  }
23191 
23194  void push_back(const typename object_t::value_type& val)
23195  {
23196  // push_back only works for null objects or objects
23197  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23198  {
23199  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
23200  }
23201 
23202  // transform null object into an object
23203  if (is_null())
23204  {
23205  m_data.m_type = value_t::object;
23206  m_data.m_value = value_t::object;
23207  assert_invariant();
23208  }
23209 
23210  // add element to object
23211  auto res = m_data.m_value.object->insert(val);
23212  set_parent(res.first->second);
23213  }
23214 
23217  reference operator+=(const typename object_t::value_type& val)
23218  {
23219  push_back(val);
23220  return *this;
23221  }
23222 
23226  {
23227  if (is_object() && init.size() == 2 && (*init.begin())->is_string())
23228  {
23229  basic_json&& key = init.begin()->moved_or_copied();
23230  push_back(typename object_t::value_type(
23231  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
23232  }
23233  else
23234  {
23235  push_back(basic_json(init));
23236  }
23237  }
23238 
23242  {
23243  push_back(init);
23244  return *this;
23245  }
23246 
23249  template<class... Args>
23250  reference emplace_back(Args&& ... args)
23251  {
23252  // emplace_back only works for null objects or arrays
23253  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23254  {
23255  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
23256  }
23257 
23258  // transform null object into an array
23259  if (is_null())
23260  {
23261  m_data.m_type = value_t::array;
23262  m_data.m_value = value_t::array;
23263  assert_invariant();
23264  }
23265 
23266  // add element to array (perfect forwarding)
23267  const auto old_capacity = m_data.m_value.array->capacity();
23268  m_data.m_value.array->emplace_back(std::forward<Args>(args)...);
23269  return set_parent(m_data.m_value.array->back(), old_capacity);
23270  }
23271 
23274  template<class... Args>
23275  std::pair<iterator, bool> emplace(Args&& ... args)
23276  {
23277  // emplace only works for null objects or arrays
23278  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23279  {
23280  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
23281  }
23282 
23283  // transform null object into an object
23284  if (is_null())
23285  {
23286  m_data.m_type = value_t::object;
23287  m_data.m_value = value_t::object;
23288  assert_invariant();
23289  }
23290 
23291  // add element to array (perfect forwarding)
23292  auto res = m_data.m_value.object->emplace(std::forward<Args>(args)...);
23293  set_parent(res.first->second);
23294 
23295  // create result iterator and set iterator to the result of emplace
23296  auto it = begin();
23297  it.m_it.object_iterator = res.first;
23298 
23299  // return pair of iterator and boolean
23300  return {it, res.second};
23301  }
23302 
23306  template<typename... Args>
23307  iterator insert_iterator(const_iterator pos, Args&& ... args) // NOLINT(performance-unnecessary-value-param)
23308  {
23309  iterator result(this);
23310  JSON_ASSERT(m_data.m_value.array != nullptr);
23311 
23312  auto insert_pos = std::distance(m_data.m_value.array->begin(), pos.m_it.array_iterator);
23313  m_data.m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
23314  result.m_it.array_iterator = m_data.m_value.array->begin() + insert_pos;
23315 
23316  // This could have been written as:
23317  // result.m_it.array_iterator = m_data.m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23318  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23319 
23320  set_parents();
23321  return result;
23322  }
23323 
23326  iterator insert(const_iterator pos, const basic_json& val) // NOLINT(performance-unnecessary-value-param)
23327  {
23328  // insert only works for arrays
23329  if (JSON_HEDLEY_LIKELY(is_array()))
23330  {
23331  // check if iterator pos fits to this JSON value
23332  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23333  {
23334  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
23335  }
23336 
23337  // insert to array and return iterator
23338  return insert_iterator(pos, val);
23339  }
23340 
23341  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
23342  }
23343 
23346  iterator insert(const_iterator pos, basic_json&& val) // NOLINT(performance-unnecessary-value-param)
23347  {
23348  return insert(pos, val);
23349  }
23350 
23353  iterator insert(const_iterator pos, size_type cnt, const basic_json& val) // NOLINT(performance-unnecessary-value-param)
23354  {
23355  // insert only works for arrays
23356  if (JSON_HEDLEY_LIKELY(is_array()))
23357  {
23358  // check if iterator pos fits to this JSON value
23359  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23360  {
23361  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
23362  }
23363 
23364  // insert to array and return iterator
23365  return insert_iterator(pos, cnt, val);
23366  }
23367 
23368  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
23369  }
23370 
23373  iterator insert(const_iterator pos, const_iterator first, const_iterator last) // NOLINT(performance-unnecessary-value-param)
23374  {
23375  // insert only works for arrays
23376  if (JSON_HEDLEY_UNLIKELY(!is_array()))
23377  {
23378  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
23379  }
23380 
23381  // check if iterator pos fits to this JSON value
23382  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23383  {
23384  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
23385  }
23386 
23387  // check if range iterators belong to the same JSON object
23388  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23389  {
23390  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
23391  }
23392 
23393  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23394  {
23395  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
23396  }
23397 
23398  // insert to array and return iterator
23399  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
23400  }
23401 
23404  iterator insert(const_iterator pos, initializer_list_t ilist) // NOLINT(performance-unnecessary-value-param)
23405  {
23406  // insert only works for arrays
23407  if (JSON_HEDLEY_UNLIKELY(!is_array()))
23408  {
23409  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
23410  }
23411 
23412  // check if iterator pos fits to this JSON value
23413  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23414  {
23415  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
23416  }
23417 
23418  // insert to array and return iterator
23419  return insert_iterator(pos, ilist.begin(), ilist.end());
23420  }
23421 
23424  void insert(const_iterator first, const_iterator last) // NOLINT(performance-unnecessary-value-param)
23425  {
23426  // insert only works for objects
23427  if (JSON_HEDLEY_UNLIKELY(!is_object()))
23428  {
23429  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
23430  }
23431 
23432  // check if range iterators belong to the same JSON object
23433  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23434  {
23435  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
23436  }
23437 
23438  // passed iterators must belong to objects
23439  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23440  {
23441  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
23442  }
23443 
23444  m_data.m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
23445  set_parents();
23446  }
23447 
23450  void update(const_reference j, bool merge_objects = false)
23451  {
23452  update(j.begin(), j.end(), merge_objects);
23453  }
23454 
23457  void update(const_iterator first, const_iterator last, bool merge_objects = false) // NOLINT(performance-unnecessary-value-param)
23458  {
23459  // implicitly convert null value to an empty object
23460  if (is_null())
23461  {
23462  m_data.m_type = value_t::object;
23463  m_data.m_value.object = create<object_t>();
23464  assert_invariant();
23465  }
23466 
23467  if (JSON_HEDLEY_UNLIKELY(!is_object()))
23468  {
23469  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
23470  }
23471 
23472  // check if range iterators belong to the same JSON object
23473  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23474  {
23475  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
23476  }
23477 
23478  // passed iterators must belong to objects
23479  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23480  {
23481  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
23482  }
23483 
23484  for (auto it = first; it != last; ++it)
23485  {
23486  if (merge_objects && it.value().is_object())
23487  {
23488  auto it2 = m_data.m_value.object->find(it.key());
23489  if (it2 != m_data.m_value.object->end())
23490  {
23491  it2->second.update(it.value(), true);
23492  continue;
23493  }
23494  }
23495  m_data.m_value.object->operator[](it.key()) = it.value();
23496 #if JSON_DIAGNOSTICS
23497  m_data.m_value.object->operator[](it.key()).m_parent = this;
23498 #endif
23499  }
23500  }
23501 
23504  void swap(reference other) noexcept (
23505  std::is_nothrow_move_constructible<value_t>::value&&
23506  std::is_nothrow_move_assignable<value_t>::value&&
23507  std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
23508  std::is_nothrow_move_assignable<json_value>::value
23509  )
23510  {
23511  std::swap(m_data.m_type, other.m_data.m_type);
23512  std::swap(m_data.m_value, other.m_data.m_value);
23513 
23514  set_parents();
23515  other.set_parents();
23516  assert_invariant();
23517  }
23518 
23521  friend void swap(reference left, reference right) noexcept (
23522  std::is_nothrow_move_constructible<value_t>::value&&
23523  std::is_nothrow_move_assignable<value_t>::value&&
23524  std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
23525  std::is_nothrow_move_assignable<json_value>::value
23526  )
23527  {
23528  left.swap(right);
23529  }
23530 
23533  void swap(array_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
23534  {
23535  // swap only works for arrays
23536  if (JSON_HEDLEY_LIKELY(is_array()))
23537  {
23538  using std::swap;
23539  swap(*(m_data.m_value.array), other);
23540  }
23541  else
23542  {
23543  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));
23544  }
23545  }
23546 
23549  void swap(object_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
23550  {
23551  // swap only works for objects
23552  if (JSON_HEDLEY_LIKELY(is_object()))
23553  {
23554  using std::swap;
23555  swap(*(m_data.m_value.object), other);
23556  }
23557  else
23558  {
23559  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));
23560  }
23561  }
23562 
23565  void swap(string_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
23566  {
23567  // swap only works for strings
23568  if (JSON_HEDLEY_LIKELY(is_string()))
23569  {
23570  using std::swap;
23571  swap(*(m_data.m_value.string), other);
23572  }
23573  else
23574  {
23575  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));
23576  }
23577  }
23578 
23581  void swap(binary_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
23582  {
23583  // swap only works for strings
23584  if (JSON_HEDLEY_LIKELY(is_binary()))
23585  {
23586  using std::swap;
23587  swap(*(m_data.m_value.binary), other);
23588  }
23589  else
23590  {
23591  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));
23592  }
23593  }
23594 
23597  void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23598  {
23599  // swap only works for strings
23600  if (JSON_HEDLEY_LIKELY(is_binary()))
23601  {
23602  using std::swap;
23603  swap(*(m_data.m_value.binary), other);
23604  }
23605  else
23606  {
23607  JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));
23608  }
23609  }
23610 
23612 
23614  // lexicographical comparison operators //
23616 
23619 
23620  // note parentheses around operands are necessary; see
23621  // https://github.com/nlohmann/json/issues/1530
23622 #define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
23623  const auto lhs_type = lhs.type(); \
23624  const auto rhs_type = rhs.type(); \
23625  \
23626  if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
23627  { \
23628  switch (lhs_type) \
23629  { \
23630  case value_t::array: \
23631  return (*lhs.m_data.m_value.array) op (*rhs.m_data.m_value.array); \
23632  \
23633  case value_t::object: \
23634  return (*lhs.m_data.m_value.object) op (*rhs.m_data.m_value.object); \
23635  \
23636  case value_t::null: \
23637  return (null_result); \
23638  \
23639  case value_t::string: \
23640  return (*lhs.m_data.m_value.string) op (*rhs.m_data.m_value.string); \
23641  \
23642  case value_t::boolean: \
23643  return (lhs.m_data.m_value.boolean) op (rhs.m_data.m_value.boolean); \
23644  \
23645  case value_t::number_integer: \
23646  return (lhs.m_data.m_value.number_integer) op (rhs.m_data.m_value.number_integer); \
23647  \
23648  case value_t::number_unsigned: \
23649  return (lhs.m_data.m_value.number_unsigned) op (rhs.m_data.m_value.number_unsigned); \
23650  \
23651  case value_t::number_float: \
23652  return (lhs.m_data.m_value.number_float) op (rhs.m_data.m_value.number_float); \
23653  \
23654  case value_t::binary: \
23655  return (*lhs.m_data.m_value.binary) op (*rhs.m_data.m_value.binary); \
23656  \
23657  case value_t::discarded: \
23658  default: \
23659  return (unordered_result); \
23660  } \
23661  } \
23662  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
23663  { \
23664  return static_cast<number_float_t>(lhs.m_data.m_value.number_integer) op rhs.m_data.m_value.number_float; \
23665  } \
23666  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
23667  { \
23668  return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_integer); \
23669  } \
23670  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
23671  { \
23672  return static_cast<number_float_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_float; \
23673  } \
23674  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
23675  { \
23676  return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_unsigned); \
23677  } \
23678  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
23679  { \
23680  return static_cast<number_integer_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_integer; \
23681  } \
23682  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
23683  { \
23684  return lhs.m_data.m_value.number_integer op static_cast<number_integer_t>(rhs.m_data.m_value.number_unsigned); \
23685  } \
23686  else if(compares_unordered(lhs, rhs))\
23687  {\
23688  return (unordered_result);\
23689  }\
23690  \
23691  return (default_result);
23692 
23694  // returns true if:
23695  // - any operand is NaN and the other operand is of number type
23696  // - any operand is discarded
23697  // in legacy mode, discarded values are considered ordered if
23698  // an operation is computed as an odd number of inverses of others
23699  static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
23700  {
23701  if ((lhs.is_number_float() && std::isnan(lhs.m_data.m_value.number_float) && rhs.is_number())
23702  || (rhs.is_number_float() && std::isnan(rhs.m_data.m_value.number_float) && lhs.is_number()))
23703  {
23704  return true;
23705  }
23706 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
23707  return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
23708 #else
23709  static_cast<void>(inverse);
23710  return lhs.is_discarded() || rhs.is_discarded();
23711 #endif
23712  }
23713 
23714  private:
23715  bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
23716  {
23717  return compares_unordered(*this, rhs, inverse);
23718  }
23719 
23720  public:
23721 #if JSON_HAS_THREE_WAY_COMPARISON
23724  bool operator==(const_reference rhs) const noexcept
23725  {
23726 #ifdef __GNUC__
23727 #pragma GCC diagnostic push
23728 #pragma GCC diagnostic ignored "-Wfloat-equal"
23729 #endif
23730  const_reference lhs = *this;
23731  JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
23732 #ifdef __GNUC__
23733 #pragma GCC diagnostic pop
23734 #endif
23735  }
23736 
23739  template<typename ScalarType>
23740  requires std::is_scalar_v<ScalarType>
23741  bool operator==(ScalarType rhs) const noexcept
23742  {
23743  return *this == basic_json(rhs);
23744  }
23745 
23748  bool operator!=(const_reference rhs) const noexcept
23749  {
23750  if (compares_unordered(rhs, true))
23751  {
23752  return false;
23753  }
23754  return !operator==(rhs);
23755  }
23756 
23759  std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
23760  {
23761  const_reference lhs = *this;
23762  // default_result is used if we cannot compare values. In that case,
23763  // we compare types.
23764  JSON_IMPLEMENT_OPERATOR(<=>, // *NOPAD*
23765  std::partial_ordering::equivalent,
23766  std::partial_ordering::unordered,
23767  lhs_type <=> rhs_type) // *NOPAD*
23768  }
23769 
23772  template<typename ScalarType>
23773  requires std::is_scalar_v<ScalarType>
23774  std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
23775  {
23776  return *this <=> basic_json(rhs); // *NOPAD*
23777  }
23778 
23779 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
23780  // all operators that are computed as an odd number of inverses of others
23781  // need to be overloaded to emulate the legacy comparison behavior
23782 
23786  bool operator<=(const_reference rhs) const noexcept
23787  {
23788  if (compares_unordered(rhs, true))
23789  {
23790  return false;
23791  }
23792  return !(rhs < *this);
23793  }
23794 
23797  template<typename ScalarType>
23798  requires std::is_scalar_v<ScalarType>
23799  bool operator<=(ScalarType rhs) const noexcept
23800  {
23801  return *this <= basic_json(rhs);
23802  }
23803 
23807  bool operator>=(const_reference rhs) const noexcept
23808  {
23809  if (compares_unordered(rhs, true))
23810  {
23811  return false;
23812  }
23813  return !(*this < rhs);
23814  }
23815 
23818  template<typename ScalarType>
23819  requires std::is_scalar_v<ScalarType>
23820  bool operator>=(ScalarType rhs) const noexcept
23821  {
23822  return *this >= basic_json(rhs);
23823  }
23824 #endif
23825 #else
23828  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23829  {
23830 #ifdef __GNUC__
23831 #pragma GCC diagnostic push
23832 #pragma GCC diagnostic ignored "-Wfloat-equal"
23833 #endif
23834  JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
23835 #ifdef __GNUC__
23836 #pragma GCC diagnostic pop
23837 #endif
23838  }
23839 
23842  template<typename ScalarType, typename std::enable_if<
23843  std::is_scalar<ScalarType>::value, int>::type = 0>
23844  friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23845  {
23846  return lhs == basic_json(rhs);
23847  }
23848 
23851  template<typename ScalarType, typename std::enable_if<
23852  std::is_scalar<ScalarType>::value, int>::type = 0>
23853  friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23854  {
23855  return basic_json(lhs) == rhs;
23856  }
23857 
23860  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23861  {
23862  if (compares_unordered(lhs, rhs, true))
23863  {
23864  return false;
23865  }
23866  return !(lhs == rhs);
23867  }
23868 
23871  template<typename ScalarType, typename std::enable_if<
23872  std::is_scalar<ScalarType>::value, int>::type = 0>
23873  friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23874  {
23875  return lhs != basic_json(rhs);
23876  }
23877 
23880  template<typename ScalarType, typename std::enable_if<
23881  std::is_scalar<ScalarType>::value, int>::type = 0>
23882  friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23883  {
23884  return basic_json(lhs) != rhs;
23885  }
23886 
23889  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23890  {
23891  // default_result is used if we cannot compare values. In that case,
23892  // we compare types. Note we have to call the operator explicitly,
23893  // because MSVC has problems otherwise.
23894  JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type))
23895  }
23896 
23899  template<typename ScalarType, typename std::enable_if<
23900  std::is_scalar<ScalarType>::value, int>::type = 0>
23901  friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
23902  {
23903  return lhs < basic_json(rhs);
23904  }
23905 
23908  template<typename ScalarType, typename std::enable_if<
23909  std::is_scalar<ScalarType>::value, int>::type = 0>
23910  friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
23911  {
23912  return basic_json(lhs) < rhs;
23913  }
23914 
23917  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
23918  {
23919  if (compares_unordered(lhs, rhs, true))
23920  {
23921  return false;
23922  }
23923  return !(rhs < lhs);
23924  }
23925 
23928  template<typename ScalarType, typename std::enable_if<
23929  std::is_scalar<ScalarType>::value, int>::type = 0>
23930  friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
23931  {
23932  return lhs <= basic_json(rhs);
23933  }
23934 
23937  template<typename ScalarType, typename std::enable_if<
23938  std::is_scalar<ScalarType>::value, int>::type = 0>
23939  friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
23940  {
23941  return basic_json(lhs) <= rhs;
23942  }
23943 
23946  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23947  {
23948  // double inverse
23949  if (compares_unordered(lhs, rhs))
23950  {
23951  return false;
23952  }
23953  return !(lhs <= rhs);
23954  }
23955 
23958  template<typename ScalarType, typename std::enable_if<
23959  std::is_scalar<ScalarType>::value, int>::type = 0>
23960  friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
23961  {
23962  return lhs > basic_json(rhs);
23963  }
23964 
23967  template<typename ScalarType, typename std::enable_if<
23968  std::is_scalar<ScalarType>::value, int>::type = 0>
23969  friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
23970  {
23971  return basic_json(lhs) > rhs;
23972  }
23973 
23976  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23977  {
23978  if (compares_unordered(lhs, rhs, true))
23979  {
23980  return false;
23981  }
23982  return !(lhs < rhs);
23983  }
23984 
23987  template<typename ScalarType, typename std::enable_if<
23988  std::is_scalar<ScalarType>::value, int>::type = 0>
23989  friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
23990  {
23991  return lhs >= basic_json(rhs);
23992  }
23993 
23996  template<typename ScalarType, typename std::enable_if<
23997  std::is_scalar<ScalarType>::value, int>::type = 0>
23998  friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
23999  {
24000  return basic_json(lhs) >= rhs;
24001  }
24002 #endif
24003 
24004 #undef JSON_IMPLEMENT_OPERATOR
24005 
24007 
24009  // serialization //
24011 
24014 #ifndef JSON_NO_IO
24017  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
24018  {
24019  // read width member and use it as indentation parameter if nonzero
24020  const bool pretty_print = o.width() > 0;
24021  const auto indentation = pretty_print ? o.width() : 0;
24022 
24023  // reset width to 0 for subsequent calls to this stream
24024  o.width(0);
24025 
24026  // do the actual serialization
24027  serializer s(detail::output_adapter<char>(o), o.fill());
24028  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24029  return o;
24030  }
24031 
24038  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
24039  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
24040  {
24041  return o << j;
24042  }
24043 #endif // JSON_NO_IO
24045 
24047  // deserialization //
24049 
24052 
24055  template<typename InputType>
24057  static basic_json parse(InputType&& i,
24058  parser_callback_t cb = nullptr,
24059  const bool allow_exceptions = true,
24060  const bool ignore_comments = false)
24061  {
24062  basic_json result;
24063  parser(detail::input_adapter(std::forward<InputType>(i)), std::move(cb), allow_exceptions, ignore_comments).parse(true, result); // cppcheck-suppress[accessMoved,accessForwarded]
24064  return result;
24065  }
24066 
24069  template<typename IteratorType>
24071  static basic_json parse(IteratorType first,
24072  IteratorType last,
24073  parser_callback_t cb = nullptr,
24074  const bool allow_exceptions = true,
24075  const bool ignore_comments = false)
24076  {
24077  basic_json result;
24078  parser(detail::input_adapter(std::move(first), std::move(last)), std::move(cb), allow_exceptions, ignore_comments).parse(true, result); // cppcheck-suppress[accessMoved]
24079  return result;
24080  }
24081 
24083  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
24084  static basic_json parse(detail::span_input_adapter&& i,
24085  parser_callback_t cb = nullptr,
24086  const bool allow_exceptions = true,
24087  const bool ignore_comments = false)
24088  {
24089  basic_json result;
24090  parser(i.get(), std::move(cb), allow_exceptions, ignore_comments).parse(true, result); // cppcheck-suppress[accessMoved]
24091  return result;
24092  }
24093 
24096  template<typename InputType>
24097  static bool accept(InputType&& i,
24098  const bool ignore_comments = false)
24099  {
24100  return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
24101  }
24102 
24105  template<typename IteratorType>
24106  static bool accept(IteratorType first, IteratorType last,
24107  const bool ignore_comments = false)
24108  {
24109  return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
24110  }
24111 
24113  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
24114  static bool accept(detail::span_input_adapter&& i,
24115  const bool ignore_comments = false)
24116  {
24117  return parser(i.get(), nullptr, false, ignore_comments).accept(true);
24118  }
24119 
24122  template <typename InputType, typename SAX>
24124  static bool sax_parse(InputType&& i, SAX* sax,
24126  const bool strict = true,
24127  const bool ignore_comments = false)
24128  {
24129  auto ia = detail::input_adapter(std::forward<InputType>(i));
24130  return format == input_format_t::json
24131  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24132  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
24133  }
24134 
24137  template<class IteratorType, class SAX>
24139  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
24141  const bool strict = true,
24142  const bool ignore_comments = false)
24143  {
24144  auto ia = detail::input_adapter(std::move(first), std::move(last));
24145  return format == input_format_t::json
24146  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24147  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
24148  }
24149 
24155  template <typename SAX>
24156  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24158  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
24160  const bool strict = true,
24161  const bool ignore_comments = false)
24162  {
24163  auto ia = i.get();
24164  return format == input_format_t::json
24165  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24166  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24167  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24168  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
24169  }
24170 #ifndef JSON_NO_IO
24177  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
24178  friend std::istream& operator<<(basic_json& j, std::istream& i)
24179  {
24180  return operator>>(i, j);
24181  }
24182 
24185  friend std::istream& operator>>(std::istream& i, basic_json& j)
24186  {
24187  parser(detail::input_adapter(i)).parse(false, j);
24188  return i;
24189  }
24190 #endif // JSON_NO_IO
24192 
24194  // convenience functions //
24196 
24200  const char* type_name() const noexcept
24201  {
24202  switch (m_data.m_type)
24203  {
24204  case value_t::null:
24205  return "null";
24206  case value_t::object:
24207  return "object";
24208  case value_t::array:
24209  return "array";
24210  case value_t::string:
24211  return "string";
24212  case value_t::boolean:
24213  return "boolean";
24214  case value_t::binary:
24215  return "binary";
24216  case value_t::discarded:
24217  return "discarded";
24218  case value_t::number_integer:
24219  case value_t::number_unsigned:
24220  case value_t::number_float:
24221  default:
24222  return "number";
24223  }
24224  }
24225 
24228  // member variables //
24230 
24231  struct data
24232  {
24234  value_t m_type = value_t::null;
24235 
24237  json_value m_value = {};
24238 
24239  data(const value_t v)
24240  : m_type(v), m_value(v)
24241  {
24242  }
24243 
24244  data(size_type cnt, const basic_json& val)
24245  : m_type(value_t::array)
24246  {
24247  m_value.array = create<array_t>(cnt, val);
24248  }
24249 
24250  data() noexcept = default;
24251  data(data&&) noexcept = default;
24252  data(const data&) noexcept = delete;
24253  data& operator=(data&&) noexcept = delete;
24254  data& operator=(const data&) noexcept = delete;
24255 
24256  ~data() noexcept
24257  {
24258  m_value.destroy(m_type);
24259  }
24260  };
24261 
24262  data m_data = {};
24263 
24264 #if JSON_DIAGNOSTICS
24266  basic_json* m_parent = nullptr;
24267 #endif
24268 
24269 #if JSON_DIAGNOSTIC_POSITIONS
24271  std::size_t start_position = std::string::npos;
24273  std::size_t end_position = std::string::npos;
24274  public:
24275  constexpr std::size_t start_pos() const noexcept
24276  {
24277  return start_position;
24278  }
24279 
24280  constexpr std::size_t end_pos() const noexcept
24281  {
24282  return end_position;
24283  }
24284 #endif
24285 
24287  // binary serialization/deserialization //
24289 
24292 
24293  public:
24296  static std::vector<std::uint8_t> to_cbor(const basic_json& j)
24297  {
24298  std::vector<std::uint8_t> result;
24299  to_cbor(j, result);
24300  return result;
24301  }
24302 
24306  {
24307  binary_writer<std::uint8_t>(o).write_cbor(j);
24308  }
24309 
24313  {
24314  binary_writer<char>(o).write_cbor(j);
24315  }
24316 
24319  static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
24320  {
24321  std::vector<std::uint8_t> result;
24322  to_msgpack(j, result);
24323  return result;
24324  }
24325 
24329  {
24330  binary_writer<std::uint8_t>(o).write_msgpack(j);
24331  }
24332 
24336  {
24337  binary_writer<char>(o).write_msgpack(j);
24338  }
24339 
24342  static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
24343  const bool use_size = false,
24344  const bool use_type = false)
24345  {
24346  std::vector<std::uint8_t> result;
24347  to_ubjson(j, result, use_size, use_type);
24348  return result;
24349  }
24350 
24354  const bool use_size = false, const bool use_type = false)
24355  {
24356  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
24357  }
24358 
24362  const bool use_size = false, const bool use_type = false)
24363  {
24364  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
24365  }
24366 
24369  static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
24370  const bool use_size = false,
24371  const bool use_type = false,
24372  const bjdata_version_t version = bjdata_version_t::draft2)
24373  {
24374  std::vector<std::uint8_t> result;
24375  to_bjdata(j, result, use_size, use_type, version);
24376  return result;
24377  }
24378 
24382  const bool use_size = false, const bool use_type = false,
24383  const bjdata_version_t version = bjdata_version_t::draft2)
24384  {
24385  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true, version);
24386  }
24387 
24391  const bool use_size = false, const bool use_type = false,
24392  const bjdata_version_t version = bjdata_version_t::draft2)
24393  {
24394  binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true, version);
24395  }
24396 
24399  static std::vector<std::uint8_t> to_bson(const basic_json& j)
24400  {
24401  std::vector<std::uint8_t> result;
24402  to_bson(j, result);
24403  return result;
24404  }
24405 
24409  {
24410  binary_writer<std::uint8_t>(o).write_bson(j);
24411  }
24412 
24416  {
24417  binary_writer<char>(o).write_bson(j);
24418  }
24419 
24422  template<typename InputType>
24424  static basic_json from_cbor(InputType&& i,
24425  const bool strict = true,
24426  const bool allow_exceptions = true,
24427  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24428  {
24429  basic_json result;
24430  auto ia = detail::input_adapter(std::forward<InputType>(i));
24431  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24432  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); // cppcheck-suppress[accessMoved]
24433  return res ? result : basic_json(value_t::discarded);
24434  }
24435 
24438  template<typename IteratorType>
24440  static basic_json from_cbor(IteratorType first, IteratorType last,
24441  const bool strict = true,
24442  const bool allow_exceptions = true,
24443  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24444  {
24445  basic_json result;
24446  auto ia = detail::input_adapter(std::move(first), std::move(last));
24447  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24448  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); // cppcheck-suppress[accessMoved]
24449  return res ? result : basic_json(value_t::discarded);
24450  }
24451 
24452  template<typename T>
24454  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24455  static basic_json from_cbor(const T* ptr, std::size_t len,
24456  const bool strict = true,
24457  const bool allow_exceptions = true,
24458  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24459  {
24460  return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
24461  }
24462 
24464  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24465  static basic_json from_cbor(detail::span_input_adapter&& i,
24466  const bool strict = true,
24467  const bool allow_exceptions = true,
24468  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24469  {
24470  basic_json result;
24471  auto ia = i.get();
24472  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24473  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24474  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler); // cppcheck-suppress[accessMoved]
24475  return res ? result : basic_json(value_t::discarded);
24476  }
24477 
24480  template<typename InputType>
24482  static basic_json from_msgpack(InputType&& i,
24483  const bool strict = true,
24484  const bool allow_exceptions = true)
24485  {
24486  basic_json result;
24487  auto ia = detail::input_adapter(std::forward<InputType>(i));
24488  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24489  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); // cppcheck-suppress[accessMoved]
24490  return res ? result : basic_json(value_t::discarded);
24491  }
24492 
24495  template<typename IteratorType>
24497  static basic_json from_msgpack(IteratorType first, IteratorType last,
24498  const bool strict = true,
24499  const bool allow_exceptions = true)
24500  {
24501  basic_json result;
24502  auto ia = detail::input_adapter(std::move(first), std::move(last));
24503  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24504  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); // cppcheck-suppress[accessMoved]
24505  return res ? result : basic_json(value_t::discarded);
24506  }
24507 
24508  template<typename T>
24510  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24511  static basic_json from_msgpack(const T* ptr, std::size_t len,
24512  const bool strict = true,
24513  const bool allow_exceptions = true)
24514  {
24515  return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24516  }
24517 
24519  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24520  static basic_json from_msgpack(detail::span_input_adapter&& i,
24521  const bool strict = true,
24522  const bool allow_exceptions = true)
24523  {
24524  basic_json result;
24525  auto ia = i.get();
24526  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24527  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24528  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict); // cppcheck-suppress[accessMoved]
24529  return res ? result : basic_json(value_t::discarded);
24530  }
24531 
24534  template<typename InputType>
24536  static basic_json from_ubjson(InputType&& i,
24537  const bool strict = true,
24538  const bool allow_exceptions = true)
24539  {
24540  basic_json result;
24541  auto ia = detail::input_adapter(std::forward<InputType>(i));
24542  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24543  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); // cppcheck-suppress[accessMoved]
24544  return res ? result : basic_json(value_t::discarded);
24545  }
24546 
24549  template<typename IteratorType>
24551  static basic_json from_ubjson(IteratorType first, IteratorType last,
24552  const bool strict = true,
24553  const bool allow_exceptions = true)
24554  {
24555  basic_json result;
24556  auto ia = detail::input_adapter(std::move(first), std::move(last));
24557  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24558  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); // cppcheck-suppress[accessMoved]
24559  return res ? result : basic_json(value_t::discarded);
24560  }
24561 
24562  template<typename T>
24564  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24565  static basic_json from_ubjson(const T* ptr, std::size_t len,
24566  const bool strict = true,
24567  const bool allow_exceptions = true)
24568  {
24569  return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24570  }
24571 
24573  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24574  static basic_json from_ubjson(detail::span_input_adapter&& i,
24575  const bool strict = true,
24576  const bool allow_exceptions = true)
24577  {
24578  basic_json result;
24579  auto ia = i.get();
24580  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24581  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24582  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict); // cppcheck-suppress[accessMoved]
24583  return res ? result : basic_json(value_t::discarded);
24584  }
24585 
24588  template<typename InputType>
24590  static basic_json from_bjdata(InputType&& i,
24591  const bool strict = true,
24592  const bool allow_exceptions = true)
24593  {
24594  basic_json result;
24595  auto ia = detail::input_adapter(std::forward<InputType>(i));
24596  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24597  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); // cppcheck-suppress[accessMoved]
24598  return res ? result : basic_json(value_t::discarded);
24599  }
24600 
24603  template<typename IteratorType>
24605  static basic_json from_bjdata(IteratorType first, IteratorType last,
24606  const bool strict = true,
24607  const bool allow_exceptions = true)
24608  {
24609  basic_json result;
24610  auto ia = detail::input_adapter(std::move(first), std::move(last));
24611  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24612  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict); // cppcheck-suppress[accessMoved]
24613  return res ? result : basic_json(value_t::discarded);
24614  }
24615 
24618  template<typename InputType>
24620  static basic_json from_bson(InputType&& i,
24621  const bool strict = true,
24622  const bool allow_exceptions = true)
24623  {
24624  basic_json result;
24625  auto ia = detail::input_adapter(std::forward<InputType>(i));
24626  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24627  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); // cppcheck-suppress[accessMoved]
24628  return res ? result : basic_json(value_t::discarded);
24629  }
24630 
24633  template<typename IteratorType>
24635  static basic_json from_bson(IteratorType first, IteratorType last,
24636  const bool strict = true,
24637  const bool allow_exceptions = true)
24638  {
24639  basic_json result;
24640  auto ia = detail::input_adapter(std::move(first), std::move(last));
24641  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24642  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); // cppcheck-suppress[accessMoved]
24643  return res ? result : basic_json(value_t::discarded);
24644  }
24645 
24646  template<typename T>
24648  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24649  static basic_json from_bson(const T* ptr, std::size_t len,
24650  const bool strict = true,
24651  const bool allow_exceptions = true)
24652  {
24653  return from_bson(ptr, ptr + len, strict, allow_exceptions);
24654  }
24655 
24657  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24658  static basic_json from_bson(detail::span_input_adapter&& i,
24659  const bool strict = true,
24660  const bool allow_exceptions = true)
24661  {
24662  basic_json result;
24663  auto ia = i.get();
24664  detail::json_sax_dom_parser<basic_json, decltype(ia)> sdp(result, allow_exceptions);
24665  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24666  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict); // cppcheck-suppress[accessMoved]
24667  return res ? result : basic_json(value_t::discarded);
24668  }
24670 
24672  // JSON Pointer support //
24674 
24677 
24681  {
24682  return ptr.get_unchecked(this);
24683  }
24684 
24685  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
24686  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
24687  reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
24688  {
24689  return ptr.get_unchecked(this);
24690  }
24691 
24695  {
24696  return ptr.get_unchecked(this);
24697  }
24698 
24699  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
24700  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
24701  const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
24702  {
24703  return ptr.get_unchecked(this);
24704  }
24705 
24708  reference at(const json_pointer& ptr)
24709  {
24710  return ptr.get_checked(this);
24711  }
24712 
24713  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
24714  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
24715  reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
24716  {
24717  return ptr.get_checked(this);
24718  }
24719 
24722  const_reference at(const json_pointer& ptr) const
24723  {
24724  return ptr.get_checked(this);
24725  }
24726 
24727  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
24728  JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
24729  const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
24730  {
24731  return ptr.get_checked(this);
24732  }
24733 
24736  basic_json flatten() const
24737  {
24738  basic_json result(value_t::object);
24739  json_pointer::flatten("", *this, result);
24740  return result;
24741  }
24742 
24745  basic_json unflatten() const
24746  {
24747  return json_pointer::unflatten(*this);
24748  }
24749 
24751 
24753  // JSON Patch functions //
24755 
24758 
24761  void patch_inplace(const basic_json& json_patch)
24762  {
24763  basic_json& result = *this;
24764  // the valid JSON Patch operations
24765  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
24766 
24767  const auto get_op = [](const string_t& op)
24768  {
24769  if (op == "add")
24770  {
24771  return patch_operations::add;
24772  }
24773  if (op == "remove")
24774  {
24775  return patch_operations::remove;
24776  }
24777  if (op == "replace")
24778  {
24779  return patch_operations::replace;
24780  }
24781  if (op == "move")
24782  {
24783  return patch_operations::move;
24784  }
24785  if (op == "copy")
24786  {
24787  return patch_operations::copy;
24788  }
24789  if (op == "test")
24790  {
24791  return patch_operations::test;
24792  }
24793 
24794  return patch_operations::invalid;
24795  };
24796 
24797  // wrapper for "add" operation; add value at ptr
24798  const auto operation_add = [&result](json_pointer & ptr, const basic_json & val)
24799  {
24800  // adding to the root of the target document means replacing it
24801  if (ptr.empty())
24802  {
24803  result = val;
24804  return;
24805  }
24806 
24807  // make sure the top element of the pointer exists
24808  json_pointer const top_pointer = ptr.top();
24809  if (top_pointer != ptr)
24810  {
24811  result.at(top_pointer);
24812  }
24813 
24814  // get reference to parent of JSON pointer ptr
24815  const auto last_path = ptr.back();
24816  ptr.pop_back();
24817  // parent must exist when performing patch add per RFC6902 specs
24818  basic_json& parent = result.at(ptr);
24819 
24820  switch (parent.m_data.m_type)
24821  {
24822  case value_t::null:
24823  case value_t::object:
24824  {
24825  // use operator[] to add value
24826  parent[last_path] = val;
24827  break;
24828  }
24829 
24830  case value_t::array:
24831  {
24832  if (last_path == "-")
24833  {
24834  // special case: append to back
24835  parent.push_back(val);
24836  }
24837  else
24838  {
24839  const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
24840  if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24841  {
24842  // avoid undefined behavior
24843  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
24844  }
24845 
24846  // default case: insert add offset
24847  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24848  }
24849  break;
24850  }
24851 
24852  // if there exists a parent it cannot be primitive
24853  case value_t::string: // LCOV_EXCL_LINE
24854  case value_t::boolean: // LCOV_EXCL_LINE
24855  case value_t::number_integer: // LCOV_EXCL_LINE
24856  case value_t::number_unsigned: // LCOV_EXCL_LINE
24857  case value_t::number_float: // LCOV_EXCL_LINE
24858  case value_t::binary: // LCOV_EXCL_LINE
24859  case value_t::discarded: // LCOV_EXCL_LINE
24860  default: // LCOV_EXCL_LINE
24861  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
24862  }
24863  };
24864 
24865  // wrapper for "remove" operation; remove value at ptr
24866  const auto operation_remove = [this, & result](json_pointer & ptr)
24867  {
24868  // get reference to parent of JSON pointer ptr
24869  const auto last_path = ptr.back();
24870  ptr.pop_back();
24871  basic_json& parent = result.at(ptr);
24872 
24873  // remove child
24874  if (parent.is_object())
24875  {
24876  // perform range check
24877  auto it = parent.find(last_path);
24878  if (JSON_HEDLEY_LIKELY(it != parent.end()))
24879  {
24880  parent.erase(it);
24881  }
24882  else
24883  {
24884  JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
24885  }
24886  }
24887  else if (parent.is_array())
24888  {
24889  // note erase performs range check
24890  parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
24891  }
24892  };
24893 
24894  // type check: top level value must be an array
24895  if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24896  {
24897  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
24898  }
24899 
24900  // iterate and apply the operations
24901  for (const auto& val : json_patch)
24902  {
24903  // wrapper to get a value for an operation
24904  const auto get_value = [&val](const string_t& op,
24905  const string_t& member,
24906  bool string_type) -> basic_json &
24907  {
24908  // find value
24909  auto it = val.m_data.m_value.object->find(member);
24910 
24911  // context-sensitive error message
24912  const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\''); // NOLINT(bugprone-unused-local-non-trivial-variable)
24913 
24914  // check if desired value is present
24915  if (JSON_HEDLEY_UNLIKELY(it == val.m_data.m_value.object->end()))
24916  {
24917  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24918  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
24919  }
24920 
24921  // check if result is of type string
24922  if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24923  {
24924  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24925  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
24926  }
24927 
24928  // no error: return value
24929  return it->second;
24930  };
24931 
24932  // type check: every element of the array must be an object
24933  if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24934  {
24935  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
24936  }
24937 
24938  // collect mandatory members
24939  const auto op = get_value("op", "op", true).template get<string_t>();
24940  const auto path = get_value(op, "path", true).template get<string_t>();
24941  json_pointer ptr(path);
24942 
24943  switch (get_op(op))
24944  {
24945  case patch_operations::add:
24946  {
24947  operation_add(ptr, get_value("add", "value", false));
24948  break;
24949  }
24950 
24951  case patch_operations::remove:
24952  {
24953  operation_remove(ptr);
24954  break;
24955  }
24956 
24957  case patch_operations::replace:
24958  {
24959  // the "path" location must exist - use at()
24960  result.at(ptr) = get_value("replace", "value", false);
24961  break;
24962  }
24963 
24964  case patch_operations::move:
24965  {
24966  const auto from_path = get_value("move", "from", true).template get<string_t>();
24967  json_pointer from_ptr(from_path);
24968 
24969  // the "from" location must exist - use at()
24970  basic_json const v = result.at(from_ptr);
24971 
24972  // The move operation is functionally identical to a
24973  // "remove" operation on the "from" location, followed
24974  // immediately by an "add" operation at the target
24975  // location with the value that was just removed.
24976  operation_remove(from_ptr);
24977  operation_add(ptr, v);
24978  break;
24979  }
24980 
24981  case patch_operations::copy:
24982  {
24983  const auto from_path = get_value("copy", "from", true).template get<string_t>();
24984  const json_pointer from_ptr(from_path);
24985 
24986  // the "from" location must exist - use at()
24987  basic_json const v = result.at(from_ptr);
24988 
24989  // The copy is functionally identical to an "add"
24990  // operation at the target location using the value
24991  // specified in the "from" member.
24992  operation_add(ptr, v);
24993  break;
24994  }
24995 
24996  case patch_operations::test:
24997  {
24998  bool success = false;
24999  JSON_TRY
25000  {
25001  // check if "value" matches the one at "path"
25002  // the "path" location must exist - use at()
25003  success = (result.at(ptr) == get_value("test", "value", false));
25004  }
25005  JSON_INTERNAL_CATCH (out_of_range&)
25006  {
25007  // ignore out of range errors: success remains false
25008  }
25009 
25010  // throw an exception if test fails
25011  if (JSON_HEDLEY_UNLIKELY(!success))
25012  {
25013  JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
25014  }
25015 
25016  break;
25017  }
25018 
25019  case patch_operations::invalid:
25020  default:
25021  {
25022  // op must be "add", "remove", "replace", "move", "copy", or
25023  // "test"
25024  JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
25025  }
25026  }
25027  }
25028  }
25029 
25032  basic_json patch(const basic_json& json_patch) const
25033  {
25034  basic_json result = *this;
25035  result.patch_inplace(json_patch);
25036  return result;
25037  }
25038 
25042  static basic_json diff(const basic_json& source, const basic_json& target,
25043  const string_t& path = "")
25044  {
25045  // the patch
25046  basic_json result(value_t::array);
25047 
25048  // if the values are the same, return empty patch
25049  if (source == target)
25050  {
25051  return result;
25052  }
25053 
25054  if (source.type() != target.type())
25055  {
25056  // different types: replace value
25057  result.push_back(
25058  {
25059  {"op", "replace"}, {"path", path}, {"value", target}
25060  });
25061  return result;
25062  }
25063 
25064  switch (source.type())
25065  {
25066  case value_t::array:
25067  {
25068  // first pass: traverse common elements
25069  std::size_t i = 0;
25070  while (i < source.size() && i < target.size())
25071  {
25072  // recursive call to compare array values at index i
25073  auto temp_diff = diff(source[i], target[i], detail::concat<string_t>(path, '/', detail::to_string<string_t>(i)));
25074  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25075  ++i;
25076  }
25077 
25078  // We now reached the end of at least one array
25079  // in a second pass, traverse the remaining elements
25080 
25081  // remove my remaining elements
25082  const auto end_index = static_cast<difference_type>(result.size());
25083  while (i < source.size())
25084  {
25085  // add operations in reverse order to avoid invalid
25086  // indices
25087  result.insert(result.begin() + end_index, object(
25088  {
25089  {"op", "remove"},
25090  {"path", detail::concat<string_t>(path, '/', detail::to_string<string_t>(i))}
25091  }));
25092  ++i;
25093  }
25094 
25095  // add other remaining elements
25096  while (i < target.size())
25097  {
25098  result.push_back(
25099  {
25100  {"op", "add"},
25101  {"path", detail::concat<string_t>(path, "/-")},
25102  {"value", target[i]}
25103  });
25104  ++i;
25105  }
25106 
25107  break;
25108  }
25109 
25110  case value_t::object:
25111  {
25112  // first pass: traverse this object's elements
25113  for (auto it = source.cbegin(); it != source.cend(); ++it)
25114  {
25115  // escape the key name to be used in a JSON patch
25116  const auto path_key = detail::concat<string_t>(path, '/', detail::escape(it.key()));
25117 
25118  if (target.find(it.key()) != target.end())
25119  {
25120  // recursive call to compare object values at key it
25121  auto temp_diff = diff(it.value(), target[it.key()], path_key);
25122  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25123  }
25124  else
25125  {
25126  // found a key that is not in o -> remove it
25127  result.push_back(object(
25128  {
25129  {"op", "remove"}, {"path", path_key}
25130  }));
25131  }
25132  }
25133 
25134  // second pass: traverse other object's elements
25135  for (auto it = target.cbegin(); it != target.cend(); ++it)
25136  {
25137  if (source.find(it.key()) == source.end())
25138  {
25139  // found a key that is not in this -> add it
25140  const auto path_key = detail::concat<string_t>(path, '/', detail::escape(it.key()));
25141  result.push_back(
25142  {
25143  {"op", "add"}, {"path", path_key},
25144  {"value", it.value()}
25145  });
25146  }
25147  }
25148 
25149  break;
25150  }
25151 
25152  case value_t::null:
25153  case value_t::string:
25154  case value_t::boolean:
25155  case value_t::number_integer:
25156  case value_t::number_unsigned:
25157  case value_t::number_float:
25158  case value_t::binary:
25159  case value_t::discarded:
25160  default:
25161  {
25162  // both primitive type: replace value
25163  result.push_back(
25164  {
25165  {"op", "replace"}, {"path", path}, {"value", target}
25166  });
25167  break;
25168  }
25169  }
25170 
25171  return result;
25172  }
25174 
25176  // JSON Merge Patch functions //
25178 
25181 
25184  void merge_patch(const basic_json& apply_patch)
25185  {
25186  if (apply_patch.is_object())
25187  {
25188  if (!is_object())
25189  {
25190  *this = object();
25191  }
25192  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25193  {
25194  if (it.value().is_null())
25195  {
25196  erase(it.key());
25197  }
25198  else
25199  {
25200  operator[](it.key()).merge_patch(it.value());
25201  }
25202  }
25203  }
25204  else
25205  {
25206  *this = apply_patch;
25207  }
25208  }
25209 
25211 };
25212 
25216 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25217 {
25218  return j.dump();
25219 }
25220 
25221 inline namespace literals
25222 {
25223 inline namespace json_literals
25224 {
25225 
25229 #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
25230  inline nlohmann::json operator ""_json(const char* s, std::size_t n)
25231 #else
25232  inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25233 #endif
25234 {
25235  return nlohmann::json::parse(s, s + n);
25236 }
25237 
25241 #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
25242  inline nlohmann::json::json_pointer operator ""_json_pointer(const char* s, std::size_t n)
25243 #else
25244  inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25245 #endif
25246 {
25247  return nlohmann::json::json_pointer(std::string(s, n));
25248 }
25249 
25250 } // namespace json_literals
25251 } // namespace literals
25253 
25255 // nonmember support //
25257 
25258 namespace std // NOLINT(cert-dcl58-cpp)
25259 {
25260 
25264 struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp)
25265 {
25266  std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
25267  {
25268  return nlohmann::detail::hash(j);
25269  }
25270 };
25271 
25272 // specialization for std::less<value_t>
25273 template<>
25274 struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
25275 {
25281  ::nlohmann::detail::value_t rhs) const noexcept
25282  {
25283 #if JSON_HAS_THREE_WAY_COMPARISON
25284  return std::is_lt(lhs <=> rhs); // *NOPAD*
25285 #else
25287 #endif
25288  }
25289 };
25290 
25291 // C++20 prohibit function specialization in the std namespace.
25292 #ifndef JSON_HAS_CPP_20
25293 
25297 inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp)
25298  is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
25299  is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
25300 {
25301  j1.swap(j2);
25302 }
25303 
25304 #endif
25305 
25306 } // namespace std
25307 
25308 #if JSON_USE_GLOBAL_UDLS
25309  #if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
25310  using nlohmann::literals::json_literals::operator ""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
25311  using nlohmann::literals::json_literals::operator ""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
25312  #else
25313  using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
25314  using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
25315  #endif
25316 #endif
25317 
25318 // #include <nlohmann/detail/macro_unscope.hpp>
25319 // __ _____ _____ _____
25320 // __| | __| | | | JSON for Modern C++
25321 // | | |__ | | | | | | version 3.12.0
25322 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
25323 //
25324 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
25325 // SPDX-License-Identifier: MIT
25326 
25327 
25328 
25329 // restore clang diagnostic settings
25330 #if defined(__clang__)
25331  #pragma clang diagnostic pop
25332 #endif
25333 
25334 // clean up
25335 #undef JSON_ASSERT
25336 #undef JSON_INTERNAL_CATCH
25337 #undef JSON_THROW
25338 #undef JSON_PRIVATE_UNLESS_TESTED
25339 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25340 #undef NLOHMANN_BASIC_JSON_TPL
25341 #undef JSON_EXPLICIT
25342 #undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
25343 #undef JSON_INLINE_VARIABLE
25344 #undef JSON_NO_UNIQUE_ADDRESS
25345 #undef JSON_DISABLE_ENUM_SERIALIZATION
25346 #undef JSON_USE_GLOBAL_UDLS
25347 
25348 #ifndef JSON_TEST_KEEP_MACROS
25349  #undef JSON_CATCH
25350  #undef JSON_TRY
25351  #undef JSON_HAS_CPP_11
25352  #undef JSON_HAS_CPP_14
25353  #undef JSON_HAS_CPP_17
25354  #undef JSON_HAS_CPP_20
25355  #undef JSON_HAS_CPP_23
25356  #undef JSON_HAS_FILESYSTEM
25357  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
25358  #undef JSON_HAS_THREE_WAY_COMPARISON
25359  #undef JSON_HAS_RANGES
25360  #undef JSON_HAS_STATIC_RTTI
25361  #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
25362 #endif
25363 
25364 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25365 // __ _____ _____ _____
25366 // __| | __| | | | JSON for Modern C++
25367 // | | |__ | | | | | | version 3.12.0
25368 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
25369 //
25370 // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann <https://nlohmann.me>
25371 // SPDX-License-Identifier: MIT
25372 
25373 
25374 
25375 #undef JSON_HEDLEY_ALWAYS_INLINE
25376 #undef JSON_HEDLEY_ARM_VERSION
25377 #undef JSON_HEDLEY_ARM_VERSION_CHECK
25378 #undef JSON_HEDLEY_ARRAY_PARAM
25379 #undef JSON_HEDLEY_ASSUME
25380 #undef JSON_HEDLEY_BEGIN_C_DECLS
25381 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25382 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25383 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25384 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25385 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25386 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
25387 #undef JSON_HEDLEY_CLANG_HAS_WARNING
25388 #undef JSON_HEDLEY_COMPCERT_VERSION
25389 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25390 #undef JSON_HEDLEY_CONCAT
25391 #undef JSON_HEDLEY_CONCAT3
25392 #undef JSON_HEDLEY_CONCAT3_EX
25393 #undef JSON_HEDLEY_CONCAT_EX
25394 #undef JSON_HEDLEY_CONST
25395 #undef JSON_HEDLEY_CONSTEXPR
25396 #undef JSON_HEDLEY_CONST_CAST
25397 #undef JSON_HEDLEY_CPP_CAST
25398 #undef JSON_HEDLEY_CRAY_VERSION
25399 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
25400 #undef JSON_HEDLEY_C_DECL
25401 #undef JSON_HEDLEY_DEPRECATED
25402 #undef JSON_HEDLEY_DEPRECATED_FOR
25403 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
25404 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
25405 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
25406 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
25407 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
25408 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
25409 #undef JSON_HEDLEY_DIAGNOSTIC_POP
25410 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
25411 #undef JSON_HEDLEY_DMC_VERSION
25412 #undef JSON_HEDLEY_DMC_VERSION_CHECK
25413 #undef JSON_HEDLEY_EMPTY_BASES
25414 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
25415 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
25416 #undef JSON_HEDLEY_END_C_DECLS
25417 #undef JSON_HEDLEY_FLAGS
25418 #undef JSON_HEDLEY_FLAGS_CAST
25419 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
25420 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
25421 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
25422 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
25423 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
25424 #undef JSON_HEDLEY_GCC_HAS_FEATURE
25425 #undef JSON_HEDLEY_GCC_HAS_WARNING
25426 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
25427 #undef JSON_HEDLEY_GCC_VERSION
25428 #undef JSON_HEDLEY_GCC_VERSION_CHECK
25429 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
25430 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
25431 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
25432 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
25433 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
25434 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
25435 #undef JSON_HEDLEY_GNUC_HAS_WARNING
25436 #undef JSON_HEDLEY_GNUC_VERSION
25437 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
25438 #undef JSON_HEDLEY_HAS_ATTRIBUTE
25439 #undef JSON_HEDLEY_HAS_BUILTIN
25440 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
25441 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
25442 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
25443 #undef JSON_HEDLEY_HAS_EXTENSION
25444 #undef JSON_HEDLEY_HAS_FEATURE
25445 #undef JSON_HEDLEY_HAS_WARNING
25446 #undef JSON_HEDLEY_IAR_VERSION
25447 #undef JSON_HEDLEY_IAR_VERSION_CHECK
25448 #undef JSON_HEDLEY_IBM_VERSION
25449 #undef JSON_HEDLEY_IBM_VERSION_CHECK
25450 #undef JSON_HEDLEY_IMPORT
25451 #undef JSON_HEDLEY_INLINE
25452 #undef JSON_HEDLEY_INTEL_CL_VERSION
25453 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
25454 #undef JSON_HEDLEY_INTEL_VERSION
25455 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
25456 #undef JSON_HEDLEY_IS_CONSTANT
25457 #undef JSON_HEDLEY_IS_CONSTEXPR_
25458 #undef JSON_HEDLEY_LIKELY
25459 #undef JSON_HEDLEY_MALLOC
25460 #undef JSON_HEDLEY_MCST_LCC_VERSION
25461 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
25462 #undef JSON_HEDLEY_MESSAGE
25463 #undef JSON_HEDLEY_MSVC_VERSION
25464 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
25465 #undef JSON_HEDLEY_NEVER_INLINE
25466 #undef JSON_HEDLEY_NON_NULL
25467 #undef JSON_HEDLEY_NO_ESCAPE
25468 #undef JSON_HEDLEY_NO_RETURN
25469 #undef JSON_HEDLEY_NO_THROW
25470 #undef JSON_HEDLEY_NULL
25471 #undef JSON_HEDLEY_PELLES_VERSION
25472 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
25473 #undef JSON_HEDLEY_PGI_VERSION
25474 #undef JSON_HEDLEY_PGI_VERSION_CHECK
25475 #undef JSON_HEDLEY_PREDICT
25476 #undef JSON_HEDLEY_PRINTF_FORMAT
25477 #undef JSON_HEDLEY_PRIVATE
25478 #undef JSON_HEDLEY_PUBLIC
25479 #undef JSON_HEDLEY_PURE
25480 #undef JSON_HEDLEY_REINTERPRET_CAST
25481 #undef JSON_HEDLEY_REQUIRE
25482 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
25483 #undef JSON_HEDLEY_REQUIRE_MSG
25484 #undef JSON_HEDLEY_RESTRICT
25485 #undef JSON_HEDLEY_RETURNS_NON_NULL
25486 #undef JSON_HEDLEY_SENTINEL
25487 #undef JSON_HEDLEY_STATIC_ASSERT
25488 #undef JSON_HEDLEY_STATIC_CAST
25489 #undef JSON_HEDLEY_STRINGIFY
25490 #undef JSON_HEDLEY_STRINGIFY_EX
25491 #undef JSON_HEDLEY_SUNPRO_VERSION
25492 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
25493 #undef JSON_HEDLEY_TINYC_VERSION
25494 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
25495 #undef JSON_HEDLEY_TI_ARMCL_VERSION
25496 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
25497 #undef JSON_HEDLEY_TI_CL2000_VERSION
25498 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
25499 #undef JSON_HEDLEY_TI_CL430_VERSION
25500 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
25501 #undef JSON_HEDLEY_TI_CL6X_VERSION
25502 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
25503 #undef JSON_HEDLEY_TI_CL7X_VERSION
25504 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
25505 #undef JSON_HEDLEY_TI_CLPRU_VERSION
25506 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
25507 #undef JSON_HEDLEY_TI_VERSION
25508 #undef JSON_HEDLEY_TI_VERSION_CHECK
25509 #undef JSON_HEDLEY_UNAVAILABLE
25510 #undef JSON_HEDLEY_UNLIKELY
25511 #undef JSON_HEDLEY_UNPREDICTABLE
25512 #undef JSON_HEDLEY_UNREACHABLE
25513 #undef JSON_HEDLEY_UNREACHABLE_RETURN
25514 #undef JSON_HEDLEY_VERSION
25515 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
25516 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
25517 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
25518 #undef JSON_HEDLEY_VERSION_ENCODE
25519 #undef JSON_HEDLEY_WARNING
25520 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
25521 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
25522 #undef JSON_HEDLEY_FALL_THROUGH
25523 
25524 
25525 
25526 #endif // INCLUDE_NLOHMANN_JSON_HPP_
namespace for Niels Lohmann
Definition: json.hpp:20114
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:21412
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:21839
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:22645
reference operator[](KeyType &&key)
access specified object element
Definition: json.hpp:22213
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:24440
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition: json.hpp:21785
reference back()
access the last element
Definition: json.hpp:22449
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value from compatible types
Definition: json.hpp:20852
basic_json patch(const basic_json &json_patch) const
applies a JSON patch to a copy of the current object
Definition: json.hpp:25032
const_reference front() const
access the first element
Definition: json.hpp:22442
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) const _reference operator[](const
access specified element via JSON Pointer
Definition: json.hpp:24700
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:21405
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&//NOLINT(cppcoreguidelines-noexcept-swap, performance-noexcept-swap) std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:23504
ReturnType value(const json_pointer &ptr, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:22393
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:22762
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:20247
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:20191
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:21377
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:20251
data(size_type cnt, const basic_json &val)
Definition: json.hpp:24244
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:24635
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:24680
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:20242
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) reference at(const
Definition: json.hpp:24714
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:20234
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:21349
const_reference operator[](KeyType &&key) const
access specified object element
Definition: json.hpp:22237
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:23581
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:21875
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:23450
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:21886
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:21426
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:23241
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) ValueType value(const
access the first element
Definition: json.hpp:22416
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition: json.hpp:22182
const_reference back() const
access the last element
Definition: json.hpp:22458
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:22540
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:23186
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&//NOLINT(cppcoreguidelines-noexcept-swap, performance-noexcept-swap) std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:23521
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:24536
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:20994
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition: json.hpp:23353
const binary_t & get_binary() const
get a binary value
Definition: json.hpp:21957
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:24620
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:20257
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:20382
reference at(KeyType &&key)
access specified object element with bounds checking
Definition: json.hpp:22045
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:21384
void update(const_iterator first, const_iterator last, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:23457
data m_data
Definition: json.hpp:24262
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:23225
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:20819
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:21035
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:24335
ReturnType value(const typename object_t::key_type &key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:22292
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:24590
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:24722
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition: json.hpp:21005
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:20840
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:24424
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:24551
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition: json.hpp:22656
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition: json.hpp:23373
ReturnType value(KeyType &&key, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:22345
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:24694
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:20358
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:22779
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:24305
static std::vector< std::uint8_t > to_bjdata(const basic_json &j, const bool use_size=false, const bool use_type=false, const bjdata_version_t version=bjdata_version_t::draft2)
create a BJData serialization of a given JSON value
Definition: json.hpp:24369
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:24415
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition: json.hpp:22692
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:20983
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition: json.hpp:22083
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:20265
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:21042
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition: json.hpp:22706
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:22470
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition: json.hpp:23326
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:20378
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:22267
ValueType & get_to(ValueType &v) const
Definition: json.hpp:21852
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:20237
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:20240
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:21313
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:25184
static void to_bjdata(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false, const bjdata_version_t version=bjdata_version_t::draft2)
create a BJData serialization of a given JSON value
Definition: json.hpp:24381
reference operator[](T *key)
Definition: json.hpp:22198
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:21979
iterator find(KeyType &&key)
find an element in a JSON object
Definition: json.hpp:22722
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:21391
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:20366
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const string_t &path="")
creates a diff as a JSON patch
Definition: json.hpp:25042
std::less< StringType > default_object_comparator_t
default object key comparator type The actual object key comparator type (object_comparator_t) may be...
Definition: json.hpp:20345
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:23217
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:24296
reference operator[](typename object_t::key_type key)
access specified object element
Definition: json.hpp:22160
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:21597
~basic_json() noexcept
destructor
Definition: json.hpp:21295
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:20924
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:23597
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:21370
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:24185
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition: json.hpp:23424
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value &&std::is_nothrow_move_assignable< json_base_class_t >::value)
copy assignment
Definition: json.hpp:21266
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:24482
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:21826
const_reference operator[](T *key) const
Definition: json.hpp:22204
data(const value_t v)
Definition: json.hpp:24239
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:22101
basic_json(const JsonRef &ref)
Definition: json.hpp:21163
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:20183
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:24361
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:21863
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:20370
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:21586
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:22063
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:21419
void swap(object_t &other)
exchanges the values
Definition: json.hpp:23549
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition: json.hpp:23404
static void to_bjdata(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false, const bjdata_version_t version=bjdata_version_t::draft2)
create a BJData serialization of a given JSON value
Definition: json.hpp:24390
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:21016
void swap(array_t &other)
exchanges the values
Definition: json.hpp:23533
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:22663
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:23275
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:23154
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:22786
binary_t & get_binary()
get a binary value
Definition: json.hpp:21945
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:21335
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:23250
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:22368
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:21027
data() noexcept=default
StringType string_t
a type for a string
Definition: json.hpp:20362
ObjectType< StringType, basic_json, default_object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.hpp:20354
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:23162
ValueType value(KeyType &&key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:22318
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:22025
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:24605
json_value m_value
the value of the current element
Definition: json.hpp:24237
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:21363
size_type count(const typename object_t::key_type &key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:22752
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:24319
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:21342
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:21356
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:24353
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition: json.hpp:24399
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:21240
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:20245
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:20832
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:22147
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:20232
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition: json.hpp:23346
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:20374
void swap(string_t &other)
exchanges the values
Definition: json.hpp:23565
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:20866
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:20249
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:22002
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition: json.hpp:20386
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:21167
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:23194
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:24312
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:21398
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:24328
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:24497
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:23307
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:21054
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) reference operator[](const
Definition: json.hpp:24686
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:24342
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:24200
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition: json.hpp:22770
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:24408
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition: json.hpp:22738
::nlohmann::json_pointer< StringType > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:20181
an internal type for a backed binary type
Definition: json.hpp:6194
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:6234
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:6200
std::uint64_t subtype_type
Definition: json.hpp:6197
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:6228
BinaryType container_type
Definition: json.hpp:6196
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:6222
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:6210
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:6249
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:6215
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:6256
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:6205
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:6241
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:6263
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:9846
binary_reader(const binary_reader &)=delete
binary_reader(binary_reader &&)=default
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition: json.hpp:9862
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:9883
binary_reader & operator=(binary_reader &&)=default
binary_reader & operator=(const binary_reader &)=delete
serialization to CBOR and MessagePack values
Definition: json.hpp:15787
void write_bson(const BasicJsonType &j)
Definition: json.hpp:15807
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:17547
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true, const bool use_bjdata=false, const bjdata_version_t bjdata_version=bjdata_version_t::draft2)
Definition: json.hpp:16487
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:17554
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:15798
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:17576
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:16160
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:15836
general exception of the basic_json class
Definition: json.hpp:4511
const int id
the id of the exception
Definition: json.hpp:4520
static std::string diagnostics(std::nullptr_t)
Definition: json.hpp:4531
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:4514
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:4526
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: json.hpp:4537
Definition: json.hpp:6496
char char_type
Definition: json.hpp:6498
file_input_adapter(const file_input_adapter &)=delete
file_input_adapter(file_input_adapter &&) noexcept=default
std::size_t get_elements(T *dest, std::size_t count=1)
Definition: json.hpp:6521
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6514
Definition: json.hpp:6541
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:6564
~input_stream_adapter()
Definition: json.hpp:6545
std::size_t get_elements(T *dest, std::size_t count=1)
Definition: json.hpp:6586
char char_type
Definition: json.hpp:6543
input_stream_adapter(const input_stream_adapter &)=delete
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter & operator=(input_stream_adapter &&)=delete
std::char_traits< char >::int_type get_character()
Definition: json.hpp:6574
input_stream_adapter(std::istream &i)
Definition: json.hpp:6555
exception indicating errors with iterators
Definition: json.hpp:4680
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4683
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:13606
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:13718
~iter_impl()=default
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:14189
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:14180
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:14143
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:14134
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:13733
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:14076
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:14116
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:13935
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.hpp:14027
iter_impl operator++(int) &
post-increment (it++)
Definition: json.hpp:13924
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:13986
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:14251
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:14289
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:13636
pointer operator->() const
dereference the iterator
Definition: json.hpp:13882
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:13743
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:14314
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:14222
iter_impl(iter_impl &&) noexcept=default
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:13631
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:14200
reference value() const
return the value of an iterator
Definition: json.hpp:14305
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:14125
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:13640
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:13634
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:13838
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:14211
iter_impl()=default
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.hpp:14067
iter_impl operator--(int) &
post-decrement (it–)
Definition: json.hpp:13975
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:13645
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:13708
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:13799
Definition: json.hpp:5462
iteration_proxy_value operator++(int) &
Definition: json.hpp:5518
iteration_proxy_value(iteration_proxy_value const &)=default
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:5527
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:5533
std::ptrdiff_t difference_type
Definition: json.hpp:5464
iteration_proxy_value(IteratorType it, std::size_t array_index_=0) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_default_constructible< string_type >::value)
Definition: json.hpp:5485
std::forward_iterator_tag iterator_category
Definition: json.hpp:5468
const string_type & key() const
return key of the iterator
Definition: json.hpp:5539
iteration_proxy_value(iteration_proxy_value &&) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_move_constructible< string_type >::value)=default
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:5575
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:5510
iteration_proxy_value & operator=(iteration_proxy_value const &)=default
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.hpp:5469
proxy class for the items() function
Definition: json.hpp:5583
iteration_proxy_value< IteratorType > end() const noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:5608
iteration_proxy(iteration_proxy const &)=default
iteration_proxy(iteration_proxy &&) noexcept=default
iteration_proxy_value< IteratorType > begin() const noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:5602
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:5592
iteration_proxy & operator=(iteration_proxy const &)=default
Definition: json.hpp:6607
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6611
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:6609
std::size_t get_elements(T *dest, std::size_t count=1)
Definition: json.hpp:6629
char_traits< char_type >::int_type get_character()
Definition: json.hpp:6615
Definition: json.hpp:15519
json_ref(json_ref &&) noexcept=default
json_ref(const value_type &value)
Definition: json.hpp:15527
json_ref(value_type &&value)
Definition: json.hpp:15523
value_type const & operator*() const
Definition: json.hpp:15558
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:15531
json_ref(Args &&... args)
Definition: json.hpp:15538
value_type moved_or_copied() const
Definition: json.hpp:15549
BasicJsonType value_type
Definition: json.hpp:15521
value_type const * operator->() const
Definition: json.hpp:15563
a template for a reverse iterator class
Definition: json.hpp:14368
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition: json.hpp:14384
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:14390
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition: json.hpp:14396
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:14402
std::ptrdiff_t difference_type
Definition: json.hpp:14370
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:14432
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:14438
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:14426
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:14408
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:14374
reference value() const
return the value of an iterator
Definition: json.hpp:14445
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:14381
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:14372
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:14420
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:14377
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:14414
Definition: json.hpp:9561
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9564
bool end_object()
Definition: json.hpp:9614
bool binary(binary_t &)
Definition: json.hpp:9599
bool number_integer(number_integer_t)
Definition: json.hpp:9579
bool start_array(std::size_t=detail::unknown_size())
Definition: json.hpp:9619
bool boolean(bool)
Definition: json.hpp:9574
bool end_array()
Definition: json.hpp:9624
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:9584
bool start_object(std::size_t=detail::unknown_size())
Definition: json.hpp:9604
bool string(string_t &)
Definition: json.hpp:9594
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9567
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:9589
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:9629
bool key(string_t &)
Definition: json.hpp:9609
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9563
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9565
typename BasicJsonType::string_t string_t
Definition: json.hpp:9566
Definition: json.hpp:9124
bool start_array(std::size_t len)
Definition: json.hpp:9292
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:9131
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:9132
bool number_integer(number_integer_t val)
Definition: json.hpp:9163
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:9371
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:9128
bool end_object()
Definition: json.hpp:9242
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:9169
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:9175
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
constexpr bool is_errored() const
Definition: json.hpp:9383
json_sax_dom_callback_parser(BasicJsonType &r, parser_callback_t cb, const bool allow_exceptions_=true, lexer_t *lexer_=nullptr)
Definition: json.hpp:9135
bool binary(binary_t &val)
Definition: json.hpp:9187
typename BasicJsonType::string_t string_t
Definition: json.hpp:9129
bool boolean(bool val)
Definition: json.hpp:9157
bool key(string_t &val)
Definition: json.hpp:9225
bool string(string_t &val)
Definition: json.hpp:9181
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:9127
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:9126
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:9130
bool end_array()
Definition: json.hpp:9324
bool start_object(std::size_t len)
Definition: json.hpp:9193
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:8818
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:8867
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:8861
json_sax_dom_parser(const json_sax_dom_parser &)=delete
bool binary(binary_t &val)
Definition: json.hpp:8879
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:8824
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true, lexer_t *lexer_=nullptr)
Definition: json.hpp:8832
bool start_object(std::size_t len)
Definition: json.hpp:8885
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:8820
bool key(string_t &val)
Definition: json.hpp:8908
bool end_object()
Definition: json.hpp:8918
typename BasicJsonType::string_t string_t
Definition: json.hpp:8823
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8821
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:8976
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool boolean(bool val)
Definition: json.hpp:8849
bool start_array(std::size_t len)
Definition: json.hpp:8936
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:8822
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool end_array()
Definition: json.hpp:8957
json_sax_dom_parser(json_sax_dom_parser &&)=default
constexpr bool is_errored() const
Definition: json.hpp:8988
bool string(string_t &val)
Definition: json.hpp:8873
bool number_integer(number_integer_t val)
Definition: json.hpp:8855
Definition: json.hpp:7058
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: json.hpp:7085
token_type
token types for the parser
Definition: json.hpp:7062
@ value_float
an floating point number – use get_number_float() for actual value
@ begin_array
the character for array begin [
@ value_string
a string – use get_string() for actual value
@ end_array
the character for array end ]
@ uninitialized
indicating the scanner is uninitialized
@ parse_error
indicating a parse error
@ value_integer
a signed integer – use get_number_integer() for actual value
@ value_separator
the value separator ,
@ end_object
the character for object end }
@ literal_true
the true literal
@ begin_object
the character for object begin {
@ value_unsigned
an unsigned integer – use get_number_unsigned() for actual value
@ literal_null
the null literal
@ end_of_input
indicating the end of the input buffer
@ name_separator
the name separator :
@ literal_or_value
a literal or the begin of a value (only for diagnostics)
@ literal_false
the false literal
lexical analysis
Definition: json.hpp:7135
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8517
void skip_whitespace()
Definition: json.hpp:8531
lexer & operator=(lexer &&)=default
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:7146
std::string get_token_string() const
Definition: json.hpp:8479
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8438
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8471
token_type scan()
Definition: json.hpp:8540
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8444
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.hpp:7144
lexer(lexer &&)=default
~lexer()=default
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8456
lexer & operator=(lexer &)=delete
lexer(const lexer &)=delete
constexpr JSON_HEDLEY_RETURNS_NON_NULL const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8504
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8450
exception indicating other library errors
Definition: json.hpp:4732
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4735
exception indicating access out of the defined range
Definition: json.hpp:4715
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4718
Definition: json.hpp:15738
output_adapter(StringType &s)
Definition: json.hpp:15749
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:15745
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.hpp:15741
output adapter for output streams
Definition: json.hpp:15690
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:15692
void write_character(CharType c) override
Definition: json.hpp:15696
output adapter for basic_string
Definition: json.hpp:15715
void write_character(CharType c) override
Definition: json.hpp:15721
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:15717
output adapter for byte vectors
Definition: json.hpp:15665
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.hpp:15667
void write_character(CharType c) override
Definition: json.hpp:15671
exception indicating a parse error
Definition: json.hpp:4627
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, BasicJsonContext context)
create a parse error exception
Definition: json.hpp:4639
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4647
const std::size_t byte
byte index of the parse error
Definition: json.hpp:4664
syntax analysis
Definition: json.hpp:12919
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:12951
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:13011
parser(InputAdapterType &&adapter, parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: json.hpp:12929
Definition: json.hpp:13423
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:13511
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:13498
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:13452
constexpr friend bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:13468
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:13485
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:13446
constexpr friend difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:13480
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:13458
primitive_iterator_t operator++(int) &noexcept
Definition: json.hpp:13491
constexpr difference_type get_value() const noexcept
Definition: json.hpp:13434
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:13473
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:13517
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:13440
primitive_iterator_t operator--(int) &noexcept
Definition: json.hpp:13504
constexpr friend bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:13463
Definition: json.hpp:18773
serializer & operator=(serializer &&)=delete
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:18788
~serializer()=default
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:19705
string_t indent_string
the indentation string
Definition: json.hpp:19702
serializer & operator=(const serializer &)=delete
const char indent_char
the indentation character
Definition: json.hpp:19700
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:18828
serializer(const serializer &)=delete
serializer(serializer &&)=delete
Definition: json.hpp:6969
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:6977
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6984
contiguous_bytes_input_adapter && get()
Definition: json.hpp:6987
exception indicating executing a member function with a wrong type
Definition: json.hpp:4698
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4701
Definition: json.hpp:6786
std::size_t get_elements(T *, std::size_t=1)
Definition: json.hpp:6812
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:6790
char char_type
Definition: json.hpp:6788
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6793
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition: json.hpp:14540
friend json_pointer operator/(const json_pointer &lhs, string_t token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:14635
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:14612
typename string_t_helper< RefStringType >::type string_t
Definition: json.hpp:14562
friend json_pointer operator/(const json_pointer &lhs, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:14642
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:14602
json_pointer(const string_t &s="")
create JSON pointer
Definition: json.hpp:14566
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:14701
friend std::ostream & operator<<(std::ostream &o, const json_pointer &ptr)
write string representation of the JSON pointer to stream
Definition: json.hpp:14593
void pop_back()
remove last reference token
Definition: json.hpp:14663
string_t to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:14572
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:14694
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:14627
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:14649
const string_t & back() const
return last reference token
Definition: json.hpp:14675
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:14687
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:14620
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.hpp:5656
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2619
#define JSON_HEDLEY_CONST
Definition: json.hpp:1832
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:1116
#define JSON_INLINE_VARIABLE
Definition: json.hpp:2518
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1462
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2578
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:70
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1727
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1620
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2545
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:25216
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:2061
bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:15435
#define JSON_CATCH(exception)
Definition: json.hpp:2544
#define JSON_ASSERT(x)
Definition: json.hpp:2571
#define JSON_THROW(exception)
Definition: json.hpp:2542
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
Definition: json.hpp:81
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:68
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2629
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1728
#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
Definition: json.hpp:12808
#define JSON_TRY
Definition: json.hpp:2543
#define NLOHMANN_JSON_NAMESPACE_END
Definition: json.hpp:155
#define JSON_NO_UNIQUE_ADDRESS
Definition: json.hpp:2524
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:15460
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:69
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition: json.hpp:2913
#define NLOHMANN_JSON_NAMESPACE_BEGIN
Definition: json.hpp:145
#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
Definition: json.hpp:12805
basic_json<> json
default specialization
Definition: json.hpp:3549
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:1117
#define JSON_EXPLICIT
Definition: json.hpp:2950
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: json.hpp:1410
#define JSON_HEDLEY_PURE
Definition: json.hpp:1801
bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:15485
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result)
Definition: json.hpp:23622
#define JSON_DIAGNOSTIC_POSITIONS
Definition: json.hpp:77
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:18112
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:17948
Target reinterpret_bits(const Source source)
Definition: json.hpp:17668
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:17809
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:18548
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.hpp:18600
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: json.hpp:18166
constexpr int kAlpha
Definition: json.hpp:17931
void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
Definition: json.hpp:18508
constexpr int kGamma
Definition: json.hpp:17932
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:18207
constexpr bool is_transparent()
Definition: json.hpp:4321
constexpr bool is_c_string()
Definition: json.hpp:4293
detail namespace with internal helper functions
Definition: json.hpp:263
input_format_t
the supported input formats
Definition: json.hpp:6484
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:6071
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:323
typename make_void< Ts... >::type void_t
Definition: json.hpp:269
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:9708
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:15660
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition: json.hpp:4402
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: json.hpp:9716
constexpr std::array< T, sizeof...(Args)> make_array(Args &&... args)
Definition: json.hpp:3349
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:12910
OutStringType concat(Args &&... args)
Definition: json.hpp:4476
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition: json.hpp:4411
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 >>, priority_tag< 0 >)
Definition: json.hpp:5243
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3644
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3650
typename std::conditional< is_usable_as_key_type< typename BasicJsonType::object_comparator_t, typename BasicJsonType::object_t::key_type, KeyTypeCVRef, RequireTransparentComparator, ExcludeObjectKeyType >::value &&!is_json_iterator_of< BasicJsonType, KeyType >::value, std::true_type, std::false_type >::type is_usable_as_basic_json_key_type
Definition: json.hpp:4143
void to_json(BasicJsonType &j, const T &b)
Definition: json.hpp:6065
typename T::pointer pointer_t
Definition: json.hpp:3635
parse_event_t
Definition: json.hpp:12893
@ value
the parser finished reading a JSON value
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition: json.hpp:4405
integer_sequence< size_t, Ints... > index_sequence
Definition: json.hpp:3264
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:5048
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:3310
typename T::value_type value_type_t
Definition: json.hpp:3629
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:327
void int_to_string(StringType &target, std::size_t value)
Definition: json.hpp:5436
T conditional_static_cast(U value)
Definition: json.hpp:4177
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition: json.hpp:4417
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3222
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.hpp:5302
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:9677
typename T::mapped_type mapped_type_t
Definition: json.hpp:3623
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition: json.hpp:3098
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:9685
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.hpp:3871
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:5618
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:9819
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:320
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3647
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:6938
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3318
std::integral_constant< bool, Value > bool_constant
Definition: json.hpp:4283
void concat_into(OutStringType &)
Definition: json.hpp:4392
typename T::key_type key_type_t
Definition: json.hpp:3626
constexpr bool value_in_range_of(T val)
Definition: json.hpp:4277
value_t
the JSON type enumeration
Definition: json.hpp:3000
@ null
null value
@ number_integer
number value (signed integer)
@ boolean
boolean value
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ string
string value
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
std::integral_constant< bool, all_signed< Types... >::value||all_unsigned< Types... >::value > same_sign
Definition: json.hpp:4200
constexpr std::size_t unknown_size()
Definition: json.hpp:8798
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6874
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:5231
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:9693
StringType to_string(std::size_t value)
Definition: json.hpp:5444
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:314
typename std::conditional< is_comparable< Comparator, ObjectKeyType, KeyTypeCVRef >::value &&!(ExcludeObjectKeyType &&std::is_same< KeyType, ObjectKeyType >::value) &&(!RequireTransparentComparator||is_detected< detect_is_transparent, Comparator >::value) &&!is_json_pointer< KeyType >::value, std::true_type, std::false_type >::type is_usable_as_key_type
Definition: json.hpp:4127
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:6325
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition: json.hpp:4408
typename T::iterator_category iterator_category_t
Definition: json.hpp:3641
decltype(input_adapter(std::declval< std::string >())) string_input_adapter_type
Definition: json.hpp:6914
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:6307
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:3029
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:9711
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:18685
typename std::conditional< is_detected< detect_erase_with_key_type, typename BasicJsonType::object_t, KeyType >::value, std::true_type, std::false_type >::type has_erase_with_key_type
Definition: json.hpp:4155
error_handler_t
how to treat decoding errors
Definition: json.hpp:18765
@ strict
throw a type_error exception in case of invalid UTF-8
@ replace
replace invalid UTF-8 sequences with U+FFFD
std::size_t concat_length()
Definition: json.hpp:4361
value_type_t< iterator_traits< iterator_t< T > >> range_value_t
Definition: json.hpp:3874
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:4825
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition: json.hpp:3723
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition: json.hpp:4396
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:5932
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:4857
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:9669
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3326
typename T::difference_type difference_type_t
Definition: json.hpp:3632
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:3208
typename T::is_transparent detect_is_transparent
Definition: json.hpp:4113
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:9689
typename std::conditional< std::is_same< T, void >::value, json_default_base, T >::type json_base_class
Definition: json.hpp:14494
typename T::reference reference_t
Definition: json.hpp:3638
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:9673
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:9704
bjdata_version_t
how to encode BJData
Definition: json.hpp:15773
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition: json.hpp:4146
typename T::key_compare detect_key_compare
Definition: json.hpp:3707
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:9697
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition: json.hpp:4414
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:9681
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:308
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:3117
std::integral_constant< bool,(std::is_signed< OfType >::value &&(sizeof(T)< sizeof(OfType)))||(same_sign< OfType, T >::value &&sizeof(OfType)==sizeof(T)) > never_out_of_range
Definition: json.hpp:4205
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition: json.hpp:4399
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)>>, index_sequence< Idx... >)
Definition: json.hpp:5131
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:9701
Definition: json.hpp:25222
Definition: json.hpp:5639
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression, cppcoreguidelines-noexcept-swap, performance-noexcept-swap) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:25297
namespace for Niels Lohmann
Definition: json.hpp:6136
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:6160
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition: json.hpp:6150
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:6140
Definition: json.hpp:3715
typename BasicJsonType::object_t object_t
Definition: json.hpp:3716
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition: json.hpp:3717
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition: json.hpp:3719
signed char char_type
Definition: json.hpp:3762
static constexpr int_type eof() noexcept
Definition: json.hpp:3776
uint64_t int_type
Definition: json.hpp:3763
static char_type to_char_type(int_type i) noexcept
Definition: json.hpp:3771
static int_type to_int_type(char_type c) noexcept
Definition: json.hpp:3766
static char_type to_char_type(int_type i) noexcept
Definition: json.hpp:3747
static constexpr int_type eof() noexcept
Definition: json.hpp:3752
unsigned char char_type
Definition: json.hpp:3738
uint64_t int_type
Definition: json.hpp:3739
static int_type to_int_type(char_type c) noexcept
Definition: json.hpp:3742
Definition: json.hpp:3732
Definition: json.hpp:3788
Definition: json.hpp:3787
decltype(input_adapter(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))) adapter_type
Definition: json.hpp:6897
Definition: json.hpp:295
std::false_type value_t
Definition: json.hpp:296
Default type
Definition: json.hpp:297
Definition: json.hpp:17796
diyfp w
Definition: json.hpp:17797
diyfp minus
Definition: json.hpp:17798
diyfp plus
Definition: json.hpp:17799
Definition: json.hpp:17935
std::uint64_t f
Definition: json.hpp:17936
int e
Definition: json.hpp:17937
int k
Definition: json.hpp:17938
Definition: json.hpp:17678
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:17702
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.hpp:17784
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:17767
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:17690
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:17684
std::uint64_t f
Definition: json.hpp:17681
int e
Definition: json.hpp:17682
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:5841
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:5816
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:5806
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:5828
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:5857
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:5745
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:5754
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:5699
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:5767
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:5793
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:5780
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:5876
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:5897
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:5886
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:5721
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:5732
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:5712
Definition: json.hpp:5693
Definition: json.hpp:5337
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition: json.hpp:5339
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3669
Definition: json.hpp:3654
Definition: json.hpp:3710
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3684
Definition: json.hpp:3679
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3699
Definition: json.hpp:3694
Definition: json.hpp:4776
Definition: json.hpp:3250
T value_type
Definition: json.hpp:3251
static constexpr std::size_t size() noexcept
Definition: json.hpp:3252
an iterator value
Definition: json.hpp:13539
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:13543
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:13545
Definition: json.hpp:3603
Definition: json.hpp:3590
Definition: json.hpp:4308
Definition: json.hpp:4104
Definition: json.hpp:3968
Definition: json.hpp:3987
Definition: json.hpp:4058
Definition: json.hpp:3908
Definition: json.hpp:3945
static constexpr auto value
Definition: json.hpp:3946
Definition: json.hpp:4061
Definition: json.hpp:4074
Definition: json.hpp:3881
Definition: json.hpp:4031
Definition: json.hpp:3941
Definition: json.hpp:3952
ConstructibleStringType laundered_type
Definition: json.hpp:3957
static constexpr auto value
Definition: json.hpp:3960
Definition: json.hpp:4077
Definition: json.hpp:3819
Definition: json.hpp:3800
Definition: json.hpp:311
Definition: json.hpp:3662
static constexpr bool value
Definition: json.hpp:3663
Definition: json.hpp:6850
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:6851
Definition: json.hpp:3834
Definition: json.hpp:4083
Definition: json.hpp:3613
Definition: json.hpp:4165
char x[2]
Definition: json.hpp:4166
Definition: json.hpp:4161
static one test(decltype(&C::capacity))
@ value
Definition: json.hpp:4172
char one
Definition: json.hpp:4162
static two test(...)
Definition: json.hpp:3853
static constexpr bool value
Definition: json.hpp:3867
Definition: json.hpp:9751
Definition: json.hpp:9720
Definition: json.hpp:4094
Definition: json.hpp:4330
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6862
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6866
iterator_input_adapter< iterator_type > adapter_type
Definition: json.hpp:6840
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6839
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6842
IteratorType iterator_type
Definition: json.hpp:6838
std::random_access_iterator_tag iterator_category
Definition: json.hpp:3430
Definition: json.hpp:3418
Definition: json.hpp:3399
Default base class of the basic_json class.
Definition: json.hpp:14487
Definition: json.hpp:266
void type
Definition: json.hpp:267
Definition: json.hpp:3794
Definition: json.hpp:281
nonesuch(nonesuch const &&)=delete
~nonesuch()=delete
void operator=(nonesuch &&)=delete
void operator=(nonesuch const &)=delete
nonesuch(nonesuch const &)=delete
abstract output adapter interface
Definition: json.hpp:15646
output_adapter_protocol(const output_adapter_protocol &)=default
virtual ~output_adapter_protocol()=default
virtual void write_character(CharType c)=0
output_adapter_protocol(output_adapter_protocol &&) noexcept=default
virtual void write_characters(const CharType *s, std::size_t length)=0
struct to capture the start position of the current token
Definition: json.hpp:3163
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:3167
std::size_t lines_read
the number of lines read
Definition: json.hpp:3169
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:3165
Definition: json.hpp:3334
Definition: json.hpp:3333
Definition: json.hpp:3339
static constexpr JSON_INLINE_VARIABLE T value
Definition: json.hpp:3340
Definition: json.hpp:6103
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.hpp:6105
Definition: json.hpp:3270
Definition: json.hpp:3289
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:3291
static constexpr bool test(T val)
Definition: json.hpp:4261
static constexpr bool test(T)
Definition: json.hpp:4270
Definition: json.hpp:4256
static constexpr bool test(T val)
Definition: json.hpp:4215
static constexpr bool test(T val)
Definition: json.hpp:4235
static constexpr bool test(T val)
Definition: json.hpp:4225
static constexpr bool test(T val)
Definition: json.hpp:4245
Definition: json.hpp:4210
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:6725
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:6667
Definition: json.hpp:6661
SAX interface.
Definition: json.hpp:8683
virtual bool binary(binary_t &val)=0
a binary value was read
virtual bool number_float(number_float_t val, const string_t &s)=0
a floating-point number was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
virtual bool key(string_t &val)=0
an object key was read
json_sax()=default
virtual bool string(string_t &val)=0
a string value was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:8684
typename BasicJsonType::string_t string_t
Definition: json.hpp:8687
virtual bool end_array()=0
the end of an array was read
json_sax(const json_sax &)=default
virtual bool boolean(bool val)=0
a boolean value was read
virtual bool end_object()=0
the end of an object was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:8686
virtual bool null()=0
a null value was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8685
json_sax(json_sax &&) noexcept=default
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:8688
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
a minimal map-like container that preserves insertion order
Definition: json.hpp:19747
const T & at(const key_type &key) const
Definition: json.hpp:19851
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:19750
const T & operator[](const key_type &key) const
Definition: json.hpp:19811
std::pair< iterator, bool > emplace(KeyType &&key, T &&t)
Definition: json.hpp:19786
typename Container::value_type value_type
Definition: json.hpp:19754
std::equal_to< Key > key_compare
Definition: json.hpp:19758
iterator erase(iterator pos)
Definition: json.hpp:19919
T mapped_type
Definition: json.hpp:19749
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition: json.hpp:19764
typename Container::iterator iterator
Definition: json.hpp:19751
T & operator[](KeyType &&key)
Definition: json.hpp:19806
iterator find(const key_type &key)
Definition: json.hpp:20003
T & at(const key_type &key)
Definition: json.hpp:19823
iterator erase(iterator first, iterator last)
Definition: json.hpp:19924
const_iterator find(const key_type &key) const
Definition: json.hpp:20029
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:20046
size_type erase(KeyType &&key)
Definition: json.hpp:19900
typename Container::size_type size_type
Definition: json.hpp:19753
const T & at(KeyType &&key) const
Definition: json.hpp:19866
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:19771
ordered_map() noexcept(noexcept(Container()))
Definition: json.hpp:19763
void insert(InputIt first, InputIt last)
Definition: json.hpp:20064
T & operator[](const key_type &key)
Definition: json.hpp:19799
size_type count(const key_type &key) const
Definition: json.hpp:19977
size_type erase(const key_type &key)
Definition: json.hpp:19879
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:20041
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition: json.hpp:19768
size_type count(KeyType &&key) const
Definition: json.hpp:19991
Key key_type
Definition: json.hpp:19748
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:19766
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition: json.hpp:20061
iterator find(KeyType &&key)
Definition: json.hpp:20017
T & at(KeyType &&key)
Definition: json.hpp:19838
typename Container::const_iterator const_iterator
Definition: json.hpp:19752
const T & operator[](KeyType &&key) const
Definition: json.hpp:19818
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition: json.hpp:25266
bool operator()(::nlohmann::detail::value_t lhs, ::nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:25280